Previous | Next | Trail Map | RMI | Using Java RMI

Compiling the Example Programs

In a real-world scenario where a service like the compute engine is deployed, a developer would likely create a JAR (Java Archive) file that contains the Compute and Task interfaces for server classes to implement and client program to use.

Next, a developer (perhaps the same developer of the interface JAR file above) would write an implementation of the Compute interface and deploy that service on a machine available to clients.

Developers of client programs can use the Compute and Task interfaces (contained in the JAR file) and independently develop a task and client program that uses a Compute service.

In this section, you learn how to set up the JAR file, server classes, and client classes. You will see that the client's Pi class will be downloaded to the server at run time. Also, the ComputeEngine's remote stub will be downloaded from the server to the client at run time.

The example separates the interfaces, remote object implementation, and client code into three different packages:

Let's first build the interface JAR file to provide to server and client developers.

Building a JAR file of Interface Classes

First you need to compile the interface source files in the compute package and then build a JAR file that contains their class files. Let's suppose that user waldo has written these particular interfaces and has placed the source files in c:\home\waldo\src\compute (on UNIX that is, /home/waldo/src/compute). Given these paths, you can use the following commands to compile the interfaces and create the JAR file:

Platform-Specific Details: Building a Jar File

Windows:

cd c:\home\waldo\src
javac compute\Compute.java 
javac compute\Task.java
jar cvf compute.jar compute\*.class

UNIX:

cd /home/waldo/src
javac compute/Compute.java 
javac compute/Task.java
jar cvf compute.jar compute/*.class

The jar command displays the following output (due to the -v option):

added manifest
adding: compute/Compute.class (in=281) (out=196) 
    	(deflated 30%)
adding: compute/Task.class (in=200) (out=164) 
    	(deflated 18%)

Now you can distribute the compute.jar file to developers of server and client applications so that they can make use of the interfaces.

In general, when you build either server- or client-side classes with the javac and rmic compilers, you need to specify where the resulting class files should reside so that they are network accessible. In this example, this location is, for UNIX, /home/user/public_html/classes because some web servers allow accessing a user's public_html directory via an HTTP URL constructed as http://host/~user/. If your web server does not support this convention, you could use a file URL instead. The file URLs take the form file:/home/user/public_html/classes/ on UNIX, or file:/c:\home\user\public_html\classes/ on Windows. You may also select another type of URL as appropriate.

The network accessibility of the class files allows the RMI runtime to download code when needed. Rather than defining its own protocol for code downloading, RMI uses URL protocols supported by Java (for example, HTTP) to download code. Note that a full, heavyweight web server is not needed to accomplish this downloading of class files. In fact, a simple HTTP server which provides all the functionality needed to make classes available for downloading in RMI via HTTP can be found at:

ftp://java.sun.com/pub/jdk1.1/rmi/class-server.zip

Building the Server Classes

The engine package contains only one server-side implementation class, ComputeEngine, the remote object implementation of the Compute interface. Since ComputeEngine is an implementation of a remote interface, you need to generate a stub for the remote object so that clients can contact the remote object.

Let's say that, ann, the developer of the ComputeEngine class, has placed ComputeEngine.java in the c:\home\ann\src\engine, directory and is deploying the class files for clients to use in a subdirectory of her public_html directory, c:\home\ann\public_html\classes (on UNIX that would be /home/ann/public_html/classes, accessible via some web servers as http://host/~ann/classes/).

Let's assume that the compute.jar file is located in the directory c:\home\ann\public_html\classes. To compile the ComputeEngine class, your class path must include the compute.jar file and the source directory itself.


A Note About Class Path: Normally, we recommend that you set the class path on the command line using the -classpath option. However, for several compounding reasons, this example uses the CLASSPATH environment variable (since both javac and rmic require a class path and the -classpath option is treated differently in JDK1.1 and JDK1.2). We recommend that you do not set CLASSPATH in a login or startup file and that you remember to unset it when you're finished working with this example.

For detailed information on CLASSPATH refer to: http://java.sun.com/products/jdk/1.2/docs/install.html


Here's how to set the CLASSPATH environment variable:


Platform-Specific Details: Setting the CLASSPATH Environment Variable

Windows:

set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar

Unix:

setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar

Now you compile the ComputeEngine.java source file and the generate a stub for the ComputeEngine class and make that stub network accessible. To create stub (and optionally skeleton files), run the rmic compiler on the fully qualified class names of the remote object implementations which must be found in the class path. The rmic command takes one or more class names as input and produces, as output, class files of the form ClassName_Stub.class (and optionallyClassName_Skel.class). A skeleton file will not be generated if you run rmic with the -v1.2 option. This option should only be used if all of your clients will be running JDK1.2 or later.

Platform-Specific Details: Compiling the Compute Engine and Its Stub

Windows:

cd c:\home\ann\src
javac engine\ComputeEngine.java
rmic -d . engine.ComputeEngine
mkdir c:\home\ann\public_html\classes\engine
cp engine\ComputeEngine_*.class
    c:\home\ann\public_html\classes\engine

Unix:

cd /home/ann/src
javac engine/ComputeEngine.java
rmic -d . engine.ComputeEngine
mkdir /home/ann/public_html/classes/engine
cp engine/ComputeEngine_*.class
    /home/ann/public_html/classes/engine

The -d option tells the rmic compiler to place the generated class files, ComputeEngine_Stub and ComputeEngine_Skel, in the directory c:\home\ann\src\engine. You also need to make the stubs and skeletons network accessible, so you must copy the stub and skeleton class to the public_html\classes area.

Since the ComputeEngine's stub implements the Compute interface, which refers to the Task interface, you need to make these two interface class files network accessible along with the stub. So, the final step is to unpack the compute.jar file in the directory c:\home\ann\public_html\classes to make the Compute and Task interfaces available for downloading.


Platform-Specific Details: Unpacking the JAR File

Windows:

cd c:\home\ann\public_html\classes
jar xvf compute.jar

Unix:

cd /home/ann/public_html/classes
jar xvf compute.jar

The jar command displays the following output:

created: META-INF/
extracted: META-INF/MANIFEST.MF
extracted: compute/Compute.class
extracted: compute/Task.class

Now the compute engine is ready to deploy. You could do that now, or wait until after you have built the client. While we are on a building spree, let's build the client-side program next.

Building the Client Classes

Let's assume that user jones has created the client code in the directory c:\home\jones\src\client and will deploy the Pi class (so that it can be downloaded to the compute engine) in the network-accessible directoryc:\home\jones\public_html\classes (also available via some web servers as http://host/~jones/classes/). The two client-side classes are contained in the files Pi.java and ComputePi.java in the client subdirectory.

In order to build the client code, you need the compute.jar file that contains the Compute and Task interfaces that the client uses. Let's say that the compute.jar file is located in c:\home\jones\public_html\classes. The client classes can be built as follows:


Platform-Specific Details: Compiling the Client

Windows:

set CLASSPATH=c:\home\jones\src;c:\home\jones\public_html\classes\compute.jar
cd c:\home\jones\src
javac client\ComputePi.java
javac -d c:\home\jones\public_html\classes client\Pi.java

UNIX:

setenv CLASSPATH /home/jones/src:/home/jones/public_html/classes/compute.jar
cd /home/jones/src
javac client/ComputePi.java
javac -d /home/jones/public_html/classes client/Pi.java

Only the Pi class needs to be placed in the directory public_html\classes\client (the client directory is created by javac if it does not exist). That is because only the Pi class needs to be available for downloading to the compute engine's virtual machine.

Now you can run the server, then the client.


Previous | Next | Trail Map | RMI | Using Java RMI