Interfaces for bootstrapping and I/O

The facet which Jnode looks for is called IBootstrapFacet, in package org.jtrix.facets1.netlet.

Our netlet needs to implement and offer an IBootstrapFacet if it is to make use of being a bootstrap netlet and read in a warrant. This means it needs two methods. The boot() method is called by the node and allows us to do all the work. The getInvocationTimeout() method simply tells the node how long it can expect the boot() call to last before it can deem the netlet to have gone wrong.

When the netlet receives the boot call it's given an interface called IManager. This is an inner class of IBootstrapFacet, and just allows the netlet to ask the node for the relevant I/O streams. Looking at the run above we can see the warrant file hello-warrant.xml is given as an argument called warrant-in. So in our case, our netlet must ask for the warrant-in stream and it will be granted read access to that file. We could have called that stream anything, not just warrant-in, but whatever we call it both the person running Jnode and the netlet must agree on it.

So, the procedure so far: our netlet offers an IBootstrapFacet. The node binds it and calls its boot() method, giving us an IManager interface. Our netlet asks this IManager interface for the input stream called warrant-in, and thus can read the warrant.

Now, in an ideal world we would ask for this input stream and get an ordinary java.io.InputStream object from which to read the warrant. Sadly, this is not an ideal world. In particular, java.io.InputStream is not serializable and that means it can't pass through facets. And if it can't get through facets then it can't get into or out of a netlet. Similarly for java.io.OutputStream. What to do?

Luckily, Jtrix has a few tricks up its sleeve. First, it has a couple of facets called IInputStream and IOutputStream. These can be found in org.jtrix.facets1.util.io. This is what we get from IManager. Second, it has utility classes FacetInputStreamWrapper and FacetOutputStreamWrapper in org.jtrix.project.libjtrix.io. These are subclasses of java.io.InputStream and java.io.OutputStream and are constructed by giving an IInputStream and IOutputStream. Thus if we're given an IInputStream we can use it to construct a FacetInputStreamWrapper and instantly we have an ordinary java.io.InputStream:


    IInputStream facet1 = // Some input stream from a facet (and it is a facet)
    InputStream stream1 = new FacetInputStreamWrapper(facet1);
    // Now variable stream1 is an ordinary java.io.InputStream

    IOutputStream facet2 = // An output stream from a facet (and it is a facet)
    OutputStream stream2 = new FacetOutputStreamWrapper(facet2);
    // Now variable stream2 is an ordinary java.io.OutputStream

    // The Warrant object in org.jtrix.base takes a java.io.InputStream
    // in its constructor. So if stream1 is reading a warrant XML file
    // then we get a Warrant like this:

    Warrant w = new Warrant(stream1);

The code below shows this in context.

Nik Silver 2002-03-09