Java's remote method invocation (RMI) framework enables you to create virtually transparent distributed services and applications. RMI-based applications consist of Java objects making method calls to one another without regard to their location. This allows one Java object to invoke methods on another Java object residing in another virtual machine in the same manner in which methods are invoked on a Java object residing in the same virtual machine.
Each remote object must be exported so that it will be available to accept incoming remote method requests. Remote objects can be exported manually by calling these methods.
A constructor that throws java.rmi.RemoteException must be defined for each remote object, since the export process can potentially fail. Listing A shows a valid implementation for our TimeKeeper remote object interface.
The RMI registry
RMI defines a remote object repository known as the RMI registry. An RMI registry is a simple name server that maintains references to remote objects and makes them available to RMI servers.
On UNIX-based systems, use following command line to start the RMI registry:
On Windows systems, use one of the following command lines to start the RMI registry:
By default, the RMI registry runs on port 1099. You can designate a different port by specifying the port number when you start the registry. For instance, the following command line will start the registry to run on port 3000 on a Windows system:
start rmiregistry 3000
For remote objects to be discovered and used, remote-object clients must connect to an RMI server containing references to the objects. An RMI server is simply a Java class that implements a main method, instantiates and exports each remote object, and binds the instances to a name in the RMI registry.
Anytime code is to be downloaded by a JVM, security must be in place to protect the system from objects performing unsafe operations. Thus, the main method of an RMI server must create and install a security manager, as the following example illustrates:
if (System.getSecurityManager() == null)
The RMI server creates instances of the remote objects and then binds them to a name that can be discovered and called by remote clients, as in the following example:
TimeKeeperImpl obj = new TimeKeeperImpl(); // instantiate the object
Naming.rebind("//myhost/TimeKeeper", obj); // bind the object to a name
When the remote object is instantiated, it is exported and made available to accept incoming calls.
Once a remote object is instantiated and bound to a name, remote callers can discover the object by name, obtain a remote object reference, and then invoke methods on the object.
The example in Listing B illustrates a simple RMI server that installs a security manager and then creates and binds one remote object.
Starting the server
Starting an RMI server simply involves running the server as you would any normal Java application; however, a couple of name/value pair properties must be defined on the command line:
- The java.rmi.server.codebase property is defined so that classes can be dynamically downloaded to the registry and then to the client.
- The java.security.policy property is defined so that the server knows what security policies to apply.
The command-line example in Listing C illustrates how to start the SimpleRMIServer, setting the java.rmi.server.codebase property to http://myhost/~jeff/remoteobjects and the java.security.policy property to $HOME/jeff/policies/policy.
After the SimpleRMIServer is started, you should see the following output:
TimeKeeper is bound in the registry
In this article, we explored how RMI is used to establish remote interaction, allowing programmers to concentrate on other issues besides the communications infrastructure. Java's remote method invocation framework enables you to create virtually transparent distributed services and applications. RMI-based applications use Java objects to make method calls to one another without regard to their location.