Jump to content

Java remote method invocation

From Alfawiki
Java Remote Method Invocation (Java RMI)
Company typeAPI
IndustrySoftware development
Area served
Software developers using Java
ProductsRemote Method Invocation API, protocols JRMP and RMI-IIOP
OwnerOracle Corporation
Websitewww.oracle.com/java/technologies/javase/javase-tech-index.html

The Java Remote Method Invocation (Java RMI) is a Java API that facilitates remote method invocation, serving as the object-oriented equivalent to remote procedure calls (RPC). It supports the direct transmission of serialized Java objects and incorporates distributed garbage collection capabilities.

Initially, its implementation depended on the Java Virtual Machine (JVM) class model, allowing communication exclusively between JVMs. This Java-specific protocol is referred to as the Java Remote Method Protocol (JRMP). To broaden compatibility beyond JVM environments, a version utilizing CORBA was introduced.

The label RMI can denote either the API itself or both the API and its associated protocols such as JRMP or IIOP. When RMI delegates operations to a CORBA infrastructure, it is specifically called RMI-IIOP.

Java RMI’s architecture, including its distributed garbage collection mechanism, is inspired by the "network objects" concept found in Modula-3.

Generalized code

The original RMI API was extended to accommodate various implementations, including those operating over HTTP. To align with RMI’s model, CORBA incorporated "call-by-value" argument passing; however, interfaces for RMI-IIOP and JRMP are not entirely congruent.

The core of RMI functionality is located within the , with Sun’s primary implementation contained in the sun.rmi package. Before Java 5.0, developers were required to generate RMI stubs separately using the rmic tool. Starting with Java 5, this compilation step became unnecessary, and static stubs were officially deprecated in Java 8.

Jini version

Jini provides an enhanced version of RMI for Java that introduces improved security measures, dynamic object discovery, and additional features designed specifically for distributed object systems.

Example

Below are classes demonstrating a simple client-server application using RMI that outputs a message.

RmiServerIntf interface
declares the methods accessible remotely by clients and implemented by the server. It extends the interface to indicate remote invocation capability.

<syntaxhighlight lang=java> import java.rmi.Remote; import java.rmi.RemoteException;

public interface RmiServerIntf extends Remote {

   String getMessage() throws RemoteException;

} </syntaxhighlight>

RmiServer class
handles incoming RMI requests and implements the remote interface for client method calls.

<syntaxhighlight lang=java> 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); // eliminates need for 'rmic' compilation
   }
   public String getMessage() {
       return MESSAGE;
   }
   public static void main(String[] args) throws Exception {
       System.out.println("RMI server started");
       try {
           LocateRegistry.createRegistry(1099);
           System.out.println("java RMI registry created.");
       } catch (RemoteException e) {
           System.out.println("java RMI registry already exists.");
       }
          
       RmiServer server = new RmiServer();
       Naming.rebind("//localhost/RmiServer", server);
       System.out.println("PeerServer bound in registry");
   }

} </syntaxhighlight>

RmiClient class
retrieves a proxy reference to the remote server object and invokes its method to fetch a message.

<syntaxhighlight lang=java> 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());
   }

} </syntaxhighlight>

Prior to executing this example, generate a stub file from the compiled '*.class' file using the RMI compiler 'rmic':

rmic RmiServer

It should be noted that since J2SE 5.0, dynamically generated stubs are supported by default. The use of 'rmic' now primarily serves legacy purposes or scenarios where no explicit port number is specified during remote object export, as outlined in the documentation.

External links