RMI: Programmer Checklist
Source
The interface
- Create public interface XYZ extends java.rmi.Remote
- Add the Remote method.
- The return type and all the parameters are Serializable: Each either:
- implements java.io.Serializable
- extends a Serializable class
- implements an interface that extends Remote directly or indirectly.
<return-type> methodName( <parameter-list> ) throws java.rmi.RemoteException;
The server (implementation of the interface)
- extends UnicastRemoteObject or its constructor invokes UnicastRemoteObject.exportObject(this) (see Javadoc).
- implements XYZ.
- has a no-argument constructor that throws RemoteException.
- The [main] method that instantiates a server object:
- set a security manager ( needed, only if the server loads classes not found in its CLASSPATH):
- construct the remote object (can throw a RemoteException: declare this in the method's throws clause or instantiate within a try-catch).
- [may need to] bind the object to its service reference String in its machine's rmiregistry by invoking the bind or rebind methods.
- Start an rmiregistry internally
(i.e., within
its
own JVM) on some port. Then, we don't have rmiregistries running in the
background on CSIL machines where people forgot to terminate the
rmiregistries
before they logged out.
Registry registry = LocateRegistry.createRegistry( 1099 ); - Bind the service into the rmiregistry:
-
if (System.getSecurityManager() == null )
{
System.setSecurityManager(new java.rmi.SecurityManager() );
}
-
registry.rebind("HelloServer", obj);//
obj refers to the constructed remote object server; "HelloServer"
illustrates the service reference String.
The client
- sets a SecurityManager (see server instructions); it downloads theserver stub.
- gets a reference to the remote object
- invokes a remote method on the reference:
- The invocation must either
- be within a try-catch block for RemoteException
- include RemoteException in the invoking method's throws clause
Hello hello = (Hello) Naming.lookup("//" + machineName + "/HelloServer"); // machineName is a String containing either the domain name or the IP address of the machine on whch the server and rmiregistry are running. This can throw various exceptions (see Java API for java.rmi.Naming.lookup): It must be within a try-catch block or the method must include these exceptions in its throws clause.
Compiling
- compile all the .java files as usual.
Running
- Establish the code base:
- put class files in your server [client] codebase that the client [server] does not need/have have in its classpath.
- give these files permission to be readable by all.
- give the path to them permission to be readable and executable by all.
- Check that this has been done successfully: Point a web browser to the directory containing the downloadable files. You must get a directory list that includes the necessary files. If you get any other response, either:
- the files are missing, or
- the permissions are not set correctly on the files or the directories.
- Specify a policy file that allows downloading of your classes. An example of a policy file that is sufficient (but dangerously permissive) is:
- Specify the codebase when you run the server.
grant
{
// Allow
everything for now
permission
java.security.AllPermission;
};
For example, the command below runs a Java application called Application. In this case, the system expects the policy file called policy to be in the directory from which the java command executes.
-
java -Djava.rmi.server.codebase=http://www.cs.ucsb.edu/~cappello/classes/ \
-Djava.security.policy=policy \
-Djava.rmi.server.useCodebaseOnly=false \
Application <command-line parameters go here>
Class files in my public_html/classes directory to be readable by all. The classes directory needs to be readable and executable by all. The trailing slash on the codebase specification is crucial.
Starting with Java 7, the Java.rmi.server.useCodebaseOnly=false is needed to enable the application to download code from another JVM (e.g., a compute engine downloading task classes from a remote client).
(See ttps://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html"> for an explanation.)
Runtime Exceptions
java.io.NotSerializableException
The object, Obj, in question either:
- must implement java.io.Serializable, or
- must both:
- implement an interface that extends Remote, and
- be exported by either:
- extending UnicastRemoteObject, or
- invoking the static method UnicastRemoteObject.exportObject( Obj )
java.rmi.ConnectException: Connection refused to host: ...
This probably is due to your server not exporting itself: Please see the first bullet point under the section above titled "The server (implementation of the interface)."
java.security.AccessControlException: access denied
The JVM may not have access to a policy file, either because:
- the command line specification of the file's location is missing
- the command line specification of the file's location is incorrect
- the command line specification of the file's location is correct but the file is missing
- the command line specification of the file's location is correct but the file is unreadable
- the command line specification of the file's location is correct and the file is readable but incorrect.

