next up previous
Next: 7 The GMI (Group Up: Ibis Programmer's Manual Previous: 5 The Satin Divide-and-Conquer

Subsections


6 Ibis RMI

Java applications typically consist of one or more threads that manipulate a collection of objects by invoking methods on these objects. Figure 5 shows an example, where a single application thread has a reference to some interface which represents an object. The thread and object are located in the same Java Virtual Machine (JVM), and the thread can use normal method invocations on the interface to manipulate the state of the object.

Figure 5: A normal invocation.
\includegraphics[width=0.7\textwidth]{normal.eps}

To turn the example of Figure 5 into a distributed RMI invocation, some small modifications must be made to the program. The interface must be turned into a remote interface by extending java.rmi.Remote, and the object must be turned into a remote object by extending java.rmi.UnicastRemoteObject. The rmic compiler, which is part of the Java Developer Kit (JDK), can then generate the required communication code. This code consist of two objects, a 'stub' and a 'skeleton', as shown in Figure 6.

Figure 6: A remote invocation with RMI.
\includegraphics[width=0.7\textwidth]{rmi-abstract.eps}

The stub object implements the application interface, and contains code to forward any method invocations it receives to a skeleton object on another JVM. The skeleton object contains code to receive these invocations, and perform them on the object. It then sends the results back to the stub, which returns them to the waiting application thread. Although RMI is not completely transparent, only small modifications to the application are required. Furthermore, the programmer does not have to write any communication code (this is generated by rmic), making RMI easy to use. Unfortunately, the way in which method invocations are handled in RMI is fixed. After the stub forwards the invocation to the skeleton, it waits for a reply message before continuing. The skeleton must therefore always send a reply back to the stub (even if the method has no result. Furthermore, a stub in RMI always serves as a 'remote reference' to a single object, which can not be changed once the stub has been created.

There is very little difference between the usage of Sun RMI and Ibis RMI. The programs are exactly the same, you only have to compile them with Ibis rmic instead of the Sun rmic.


6.1 Compiling and running an Ibis RMI program

Before running an Ibis RMI application it must be compiled. Using ant, this is quite easy. Here is an example build.xml file:

<project
    name="Project name"
    default="build"
    basedir=".">

    <description>
    Ibis RMI application build.
    </description>

    <property environment="env" />
    <property name="ibis"   value="${env.IBIS_ROOT}" />

    <property name="build"  location="build"/>

    <import file="${ibis}/build-files/apps/build-rmi-app.xml"/>
</project>

Again, we assume that the environment variable IBIS_ROOT reflects the location of your Ibis installation.

Invoking ant build-sun compiles a standard Java RMI version of the application, leaving the class files in a directory called build. Invoking ant build compiles the application for Ibis RMI. Running an Ibis RMI program is very much like running an Ibis application.

To test this for yourself, it is best to start with an example, say $IBIS_ROOT/apps/rmi/tsp. If you want to test your own application, it is easiest to just copy the build.xml file from $IBIS_ROOT/apps/rmi/tsp, and adapt it for your application. To compile the TSP example, please type

$ ../../../ant clean build-sun
Now, this example application will be compiled with Sun RMI. Running the TSP example with Sun RMI can be done as follows. Run the command

$ java \
    -cp $IBIS_ROOT/build/ibis.jar:$IBIS_ROOT/3rdparty/log4j-1.2.9.jar:build \
    -Dibis.pool.total_hosts=2 -Dibis.pool.server.host=localhost \
    Server table_15.1
in two seperate shells. The application should now run ``in parallel'' on the local machine. Alternatively, you can use the ibis-run script:

$ $IBIS_ROOT/bin/ibis-run -nhosts 2 -hostno 0 Server table_15.1

in the first shell, and

$ $IBIS_ROOT/bin/ibis-run -nhosts 2 -hostno 1 Server table_15.1

in the second.

The TSP application uses the PoolInfo class that comes with Ibis. This utility class can be used both with Sun RMI and Ibis RMI. This class is there for convenience, it provides some methods to retrieve the number of processors in the parallel run and the ranks of the participating processors. Because this class comes with Ibis, ibis.jar has to be in the classpath, even when running with Sun RMI. The PoolInfo class needs the ibis.pool.total_hosts and ibis.pool.server.host properties in order to be able to assign ranks to processors. The pool server is started automatically when you start an ibis nameserver with the ibis-namesever script (in the case of this example, this is done automatically).

Now, we can run the same application with Ibis RMI as follows. Remember that you first have to recompile it with the Ibis rmic:

$ ../../../ant clean build
Now we can run it by typing the following command in two seperate shells:

$ java \
    -cp $IBIS_ROOT/build/ibis.jar:$IBIS_ROOT/3rdparty/log4j-1.2.9.jar:build \
    -Dibis.pool.total_hosts=2 -Dibis.pool.server.host=localhost \
    -Dibis.name_server.host=localhost -Dibis.name_server.key=bla \
    Server table_15.1

This should produce the same result as the Sun RMI test. If you want to run the application with the ibis-run script, you can use the same commandline as with the Sun RMI test.


next up previous
Next: 7 The GMI (Group Up: Ibis Programmer's Manual Previous: 5 The Satin Divide-and-Conquer
Ceriel JH Jacobs 2006-02-13