The setup procedure shouldThe Server -- UnicastRemoteObject
- Create and install a security manager
- Create one or more instances of a remote object
- Register at least one of the remote objects with the RMI remote object registry (or another naming service such as one that uses JNDI), for bootstrapping purposes
package compute; import java.rmi.Remote; import java.rmi.RemoteException; public interface Compute extends Remote { Object executeTask(Task t) throws RemoteException; } ------------------------------------------------------------------------- package compute; import java.io.Serializable; public interface Task extends Serializable { Object execute(); } -------------------------------------------------------------------------- package engine; import java.rmi.*; import java.rmi.server.*; import compute.*; public class ComputeEngine extends UnicastRemoteObject implements Compute { public ComputeEngine() throws RemoteException { super(); } public Object executeTask(Task t) { return t.execute(); } public static void main(String[] args) { if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } String name = "//host/Compute"; try { Compute engine = new ComputeEngine(); Naming.rebind(name, engine); System.out.println("ComputeEngine bound"); } catch (Exception e) { System.err.println("ComputeEngine exception: " + e.getMessage()); e.printStackTrace(); } } }
UnicastRemoteObject is a convenience class, defined in the RMI public API, that can be used as a superclass for remote object implementations. The superclass UnicastRemoteObject supplies implementations for a number of java.lang.Object methods (equals, hashCode, toString) so that they are defined appropriately for remote objects. UnicastRemoteObject also includes constructors and static methods used to export a remote object, that is, make the remote object available to receive incoming calls from clients. Once the export step is complete, the ComputeEngine remote object is ready to accept incoming calls from clients on an anonymous port, one chosen by RMI or the underlying operating system.The Server -- Security ManagersA remote object implementation does not have to extend UnicastRemoteObject, but any implementation that does not must supply appropriate implementations of the java.lang.Object methods. Furthermore, a remote object implementation must make an explicit call to one of UnicastRemoteObject's exportObject methods to make the RMI runtime aware of the remote object so that the object can accept incoming calls. By extending UnicastRemoteObject, the ComputeEngine class can be used to create a simple remote object that supports unicast (point-to-point) remote communication and that uses RMI's default sockets-based transport for communication.
Security manager protect access to system resources from untrusted downloaded code running within the virtual machine. The security manager determines whether downloaded code has access to the local file system or can perform any other privileged operations.The Server -- The RegistryAll programs using RMI must install a security manager, or RMI will not download classes (other than from the local class path) for objects received as parameters, return values, or exceptions in remote method calls. This restriction ensures that the operations performed by downloaded code go through a set of security checks.
The ComputeEngine uses a security manager supplied as part of the RMI system, the RMISecurityManager. This security manager enforces a similar security policy as the typical security manager for applets; that is to say, it is very conservative as to what access it allows.
Note the following about the arguments to the call to Naming.rebind.
- The first parameter is a URL-formatted java.lang.String representing the location and the name of the remote object. You will need to change the value of host to be the name, or IP address, of your server machine. If the host is omitted from the URL, the host defaults to the local host. Also, you don't need to specify a protocol in the URL. For example, supplying Compute as the name in the Naming.rebind call is allowed. Optionally a port number may be supplied in the URL; for example, the name //host:1234/objectname is legal. If the port is omitted, it defaults to 1099. You must specify the port number only if a server creates a registry on a port other than the default 1099. The default port is useful in that it provides a well-known place to look for the remote objects that offer services on a particular host.
- The RMI runtime substitutes a reference to the stub for the remote object reference specified by the argument. Remote implementation objects, such as instances of ComputeEngine, never leave the VM where they are created, so when a client performs a lookup in a server's remote object registry, a reference to the stub is returned. As discussed earlier, remote objects in such cases are passed by reference rather than by value.
Note that for security reasons, an application can bind, unbind, or rebind remote object references only with a registry running on the same host. This restriction prevents a remote client from removing or overwriting any of the entries in a server's registry. A lookup, however, can be requested from any host, local or remote.