Using Java RMI |
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 theCompute
andTask
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
andTask
interfaces (contained in the JAR file) and independently develop a task and client program that uses aCompute
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, theComputeEngine
'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.
compute
(Compute
andTask
interfaces)engine
(ComputeEngine
implementation and class and its stub)client
(ComputePi
client code andPi
task implementation)Building a JAR file of Interface Classes
First you need to compile the interface source files in thecompute
package and then build a JAR file that contains their class files. Let's suppose that userwaldo
has written these particular interfaces and has placed the source files inc:\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:Now you can distribute the
Platform-Specific Details: Building a Jar FileWindows:
cd c:\home\waldo\src javac compute\Compute.java javac compute\Task.java jar cvf compute.jar compute\*.classUNIX:
cd /home/waldo/src javac compute/Compute.java javac compute/Task.java jar cvf compute.jar compute/*.classThe
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%)
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
andrmic
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'spublic_html
directory via an HTTP URL constructed ashttp://host/~user/
. If your web server does not support this convention, you could use a file URL instead. The file URLs take the formfile:/home/user/public_html/classes/
on UNIX, orfile:/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.zipBuilding the Server Classes
Theengine
package contains only one server-side implementation class,ComputeEngine
, the remote object implementation of theCompute
interface. SinceComputeEngine
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 theComputeEngine
class, has placedComputeEngine.java
in thec:\home\ann\src\engine
, directory and is deploying the class files for clients to use in a subdirectory of herpublic_html
directory,c:\home\ann\public_html\classes
(on UNIX that would be/home/ann/public_html/classes
, accessible via some web servers ashttp://host/~ann/classes/
).Let's assume that the
compute.jar
file is located in the directoryc:\home\ann\public_html\classes
. To compile theComputeEngine
class, your class path must include thecompute.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 theCLASSPATH
environment variable (since bothjavac
andrmic
require a class path and the-classpath
option is treated differently in JDK1.1 and JDK1.2). We recommend that you do not setCLASSPATH
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:Now you compile the
Platform-Specific Details: Setting the CLASSPATH Environment VariableWindows:
set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jarUnix:
setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar
ComputeEngine.java
source file and the generate a stub for theComputeEngine
class and make that stub network accessible. To create stub (and optionally skeleton files), run thermic
compiler on the fully qualified class names of the remote object implementations which must be found in the class path. Thermic
command takes one or more class names as input and produces, as output, class files of the formClassName_Stub.class
(and optionallyClassName_Skel.class
). A skeleton file will not be generated if you runrmic
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 StubWindows:
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\engineUnix:
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 thermic
compiler to place the generated class files,ComputeEngine_Stub
andComputeEngine_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 thepublic_html\classes
area.Since the
ComputeEngine
's stub implements theCompute
interface, which refers to theTask
interface, you need to make these two interface class files network accessible along with the stub. So, the final step is to unpack thecompute.jar
file in the directoryc:\home\ann\public_html\classes
to make theCompute
andTask
interfaces available for downloading.
Platform-Specific Details: Unpacking the JAR FileWindows:
cd c:\home\ann\public_html\classes jar xvf compute.jarUnix:
cd /home/ann/public_html/classes jar xvf compute.jarThe
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 userjones
has created the client code in the directoryc:\home\jones\src\client
and will deploy thePi
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 ashttp://host/~jones/classes/
). The two client-side classes are contained in the filesPi.java
andComputePi.java
in theclient
subdirectory.In order to build the client code, you need the
compute.jar
file that contains theCompute
andTask
interfaces that the client uses. Let's say that thecompute.jar
file is located inc:\home\jones\public_html\classes
. The client classes can be built as follows:
Platform-Specific Details: Compiling the ClientWindows:
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.javaUNIX:
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 directorypublic_html\classes\client
(theclient
directory is created byjavac
if it does not exist). That is because only thePi
class needs to be available for downloading to the compute engine's virtual machine.Now you can run the server, then the client.
Using Java RMI |