Trail: RMI
Section: Compiling and Running the Example
Running the Example Programs
Running the Example Programs

A Note about Security

The JDK 1.2 security model is more sophisticated than the model used for JDK 1.1. JDK 1.2 contains enhancements for finer-grained security and requires code to be granted specific permissions to be allowed to perform certain operations.

In JDK 1.1 code in the class path is trusted and can perform any operation; downloaded code is governed by the rules of the installed security manager. If you run this example in JDK 1.2, you need to specify a policy file when you run your server and client. Here is a general policy file that allows downloaded code, from any code base, to do two things:

Here is the code for the general policy file:

grant {
    permission java.net.SocketPermission "*:1024-65535",
        "connect,accept";
    permission java.net.SocketPermission "*:80", "connect";
};

If you make your code available for downloading via HTTP URLs, you should use the preceding policy file when you run this example. However, if you use file URLs instead, you can use the following policy file. Note that in Windows-style file names, the backslash character needs to be represented by two backslash characters in the policy file.

grant {
    permission java.net.SocketPermission "*:1024-65535",
        "connect,accept";
    permission java.io.FilePermission
        "c:\\home\\ann\\public_html\\classes\\-", "read";
    permission java.io.FilePermission
        "c:\\home\\jones\\public_html\\classes\\-", "read";
};

This example assumes that the policy file is called java.policy and that it contains the appropriate permissions. If you run this example on JDK 1.1, you will not need to use a policy file, since the RMISecurityManager provides all of the protection you need.

Start the Server

Before starting the compute engine, you need to start RMI's registry, using the rmiregistry command. As discussed earlier, the RMI registry is a simple server-side bootstrap naming facility that allows remote clients to get a reference to a remote object. Note that before you start the rmiregistry, you must make sure that the shell or window in which you will run rmiregistry either has no CLASSPATH environment variable set or has a CLASSPATH environment variable that does not include the path to any classes, including the stubs for your remote object implementation classes, that you want downloaded to clients of your remote objects.

If you do start the rmiregistry and it can find your stub classes in CLASSPATH, it will not remember that the loaded stub class can be loaded from your server's code base, specified by the java.rmi.server.codebase property when you started up your server application. Therefore, the rmiregistry will not convey to clients the true code base associated with the stub class and, consequently, your clients will not be able to locate and to load the stub class or other server-side classes.

To start the registry on the server, execute the rmiregistry command. This command produces no output and is typically run in the background. For this example, we will start the registry on the host zaphod.


Microsoft Windows (use javaw if start is not available):
unset CLASSPATH
start rmiregistry
UNIX:
unsetenv CLASSPATH
rmiregistry &

By default, the registry runs on port 1099. To start the registry on a different port, specify the port number on the command line. Do not forget to unset your CLASSPATH.


Microsoft Windows:
start rmiregistry 2001
UNIX:
rmiregistry 2001 &

Once the registry is started, you can start the server. First, you need to make sure that both the compute.jar file and the remote object implementation class (since that is what you are starting) are in your class path.


Microsoft 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

When you start the compute engine, you need to specify, using the java.rmi.server.codebase property, where the server's classes will be made available. In this example the server-side classes to be made available for downloading are the ComputeEngine's stub and the Compute and the Task interfaces, available in ann's public_html\classes directory. Here, we start the compute engine server on the host zaphod, the same host where we started the registry.


Microsoft Windows:
java -Djava.rmi.server.codebase=file:/c:\home\ann\public_html\classes/
     -Djava.rmi.server.hostname=zaphod.east.sun.com
     -Djava.security.policy=java.policy
        engine.ComputeEngine
UNIX:
java -Djava.rmi.server.codebase=http://zaphod/~ann/classes/
     -Djava.rmi.server.hostname=zaphod.east.sun.com
     -Djava.security.policy=java.policy
        engine.ComputeEngine

The preceding java command defines several properties.

The ComputeEngine's stub class is dynamically loaded into a client's virtual machine only when the class is not already available locally and the java.rmi.server.codebas e property has been set properly, to the network-accessible location of the stub class, when the server is started. Once such a stub is loaded, it will not need to be reloaded for additional references to Com-puteEngine's objects.

Start the Client

Once the registry and the engine are running, you can start the client, specifying

First, set the CLASSPATH to see jones's client and the JAR file containing the interfaces. Then start the client on another host (one named ford, for example) as follows:


Microsoft Windows:
set CLASSPATH c:\home\jones\src;c:\home\jones\public_html\classes\compute.jar
java -Djava.rmi.server.codebase=file:/c:\home\jones\public_html\classes/
     -Djava.security.policy=java.policy
	client.ComputePi zaphod.east.sun.com 20
UNIX:
setenv CLASSPATH /home/jones/src:/home/jones/public_html/classes/compute.jar
java -Djava.rmi.server.codebase=http://ford/~jones/classes/
     -Djava.security.policy=java.policy 
        client.ComputePi zaphod.east.sun.com 20

Note that the class path is set on the command line so that the interpreter can find jones's client and the JAR file containing the interfaces.

After starting the client, you should see the following output on your display:

3.14159265358979323846

The following figure illustrates where the rmiregistry, the ComputeEngine server, and the ComputePi client obtain classes during program execution.

When the ComputeEngine server binds its remote object reference in the registry, the registry downloads the ComputeEngine_Stub, as well as the Compute and the Task interfaces on which the stub class depends. These classes are downloaded from the ComputeEngine's web server or file system, as the case may be.

The ComputePi client loads the ComputeEngine_Stub, also from the Compute-Engine's web server, as a result of the Naming.lookup call. Since the ComputePi client has both the Compute and the Task interfaces available in its class path, those classes are loaded from the class path, not the remote location.

Finally, the Pi class is loaded into the ComputeEngine's virtual machine when the Pi object is passed in the executeTask remote call to the ComputeEngine object. The Pi class is loaded from the client's web server.

Previous page: Compiling the Example Programs
Next page: End of Trail