In computing, the Java Remote Method Invocation (Java RMI) is a Java API that performs remote method invocation, the object-oriented equivalent of remote procedure calls (RPC), with support for direct transfer of serialized Java classes and distributed garbage-collection.
The original implementation depends on Java Virtual Machine (JVM) class-representation mechanisms and it thus only supports making calls from one JVM to another. The protocol underlying this Java-only implementation is known as Java Remote Method Protocol (JRMP). In order to support code running in a non-JVM context, programmers later developed a CORBA version.
Usage of the term RMI may denote solely the programming interface or may signify both the API and JRMP, IIOP, or another implementation, whereas the term RMI-IIOP (read: RMI over IIOP) specifically denotes the RMI interface delegating most of the functionality to the supporting CORBA implementation.
The basic idea of Java RMI, the distributed garbage-collection (DGC) protocol, and much of the architecture underlying the original Sun implementation, come from the "network objects" feature of Modula-3.
Generalized code
The programmers of the original RMI API generalized the code somewhat to support different implementations, such as a HTTP transport. Additionally, the ability to pass arguments "by value" was added to CORBA in order to be compatible with the RMI interface. Still, the RMI-IIOP and JRMP implementations do not have fully identical interfaces.
RMI functionality comes in the package , while most of Sun's implementation is located in the sun.rmi package. Note that with Java versions before Java 5.0 developers had to compile RMI stubs in a separate compilation step using rmic. Version 5.0 of Java and beyond no longer require this step.
Jini version
Jini offers a more advanced version of RMI in Java. It functions similarly but provides more advanced security, object discovery capabilities, and other mechanisms for distributed object applications.
Example
The following classes implement a simple client-server program using RMI that displays a message.
RmiServerIntf interface defines the interface that is used by the client and implemented by the server.
import java.rmi.Remote; import java.rmi.RemoteException;
public interface RmiServerIntf extends Remote {
String getMessage() throws RemoteException; }
RmiServer class listens to RMI requests and implements the interface which is used by the client to invoke remote methods.
import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.rmi.registry.*;
public class RmiServer extends UnicastRemoteObject implements RmiServerIntf {
public static final String MESSAGE = "Hello World";
public RmiServer() throws RemoteException {
super(0); // required to avoid the 'rmic' step, see below
}
public String getMessage() {
return MESSAGE; }
public static void main(String args[]) throws Exception {
System.out.println("RMI server started");
try { //special exception handler for registry creation
LocateRegistry.createRegistry(1099); System.out.println("java RMI registry created."); } catch (RemoteException e) { //do nothing, error means registry already exists System.out.println("java RMI registry already exists."); }
//Instantiate RmiServer
RmiServer server = new RmiServer();
// Bind this object instance to the name "RmiServer" Naming.rebind("//localhost/RmiServer", server); System.out.println("PeerServer bound in registry"); } }
RmiClient class this is the client which gets the reference (a proxy) to the remote object living on the server and invokes its method to get a message. If the server object implemented java.io.Serializable instead of java.rmi.Remote, it would be serialized and passed to the client as a value.
import java.rmi.Naming;
public class RmiClient {
public static void main(String args[]) throws Exception {
RmiServerIntf server = (RmiServerIntf)Naming.lookup("//localhost/RmiServer"); System.out.println(server.getMessage()); } }
Before running this example, we need to make a 'stub' file for the interface we used. For this task we have the RMI compiler - 'rmic' Note: we make a stub file from the '*.class' file with the implementation of the remote interface, not from the '*.java' file.