Java Remote Method Invocation (RMI) In Java we implement object systems: JVM 1 JVM 2 distribution scheme thread 1 thread 2 execution scheme O1 O2 O3
Programs/objects running on different virtual machines: separately compiled/linked allocated in different address spaces object by value message passing Approach: (very natural in object technology) definition of behavior interface implementation of behavior class
The concept client object client object server object server object STUB SKELETON server object server object
RMI architecture layers client server stubs & skeletons stubs & skeletons RMI system remote reference layer remote reference layer transport layer
Stubs: plays the role of PROXY Skeletons: helper class: generated automatically (Java 2: new protocol + reflection classes no skeleton class)
Remote Reference Layer (RRL) RRL defines the invocation semantics Connections: unicast, point-to-point (currently) Stages: server instantiates service exporting to RMI optional: naming and registering (Java 2: activable remote object (i.e. “on-demand instantiation”)
On TCP/IP: Java Remote Method Protocol (JRMP) network cable Transport layer JRE JRE JRE JRE Host OS Host OS Network layer Network layer On TCP/IP: Java Remote Method Protocol (JRMP) Other proprietary protocols are also in use!! (Java 2 v1.3: RMI-IIOP (straight link to CORBA))
The big question: How can a client find a particular service? Naming The big question: How can a client find a particular service? RMI registry lookup register client server stubs & skeletons stubs & skeletons RMI
RMI can use various directory services. RMI includes: rmiregistry service: - the registry service runs on each machine, which hosts remote objects and accepts requests for services - default TCP/IP port: 1099 Client: the RMI registry service provides lookup method specification of required remote object service: URL rmi://<host_name> [:<name_service_port>] /<service_name>
Using RMI Components of an RMI based application: interface definitions for remote services implementations of remote services stub and skeleton files server(s) to host the services RMI naming service client program optional: class file provider Example: remote calculator service and client program
Step 1: write and compile service interfaces import java.rmi.Remote; import java.rmi.RemoteException; public interface Calculator extends Remote { public long add(long a, long b) throws RemoteException; public long sub(long a, long b) throws RemoteException; public long mul(long a, long b) throws RemoteException; public long div(long a, long b) throws RemoteException; }
Step 2: write and compile service implementation import java.rmi.server.UnicastRemoteObject; import java.rmi.RemoteException; public class CalculatorImpl extends UnicastRemoteObject implements Calculator { // Implementations must have an explicit constructor // in order to declare the RemoteException exception public CalculatorImpl() throws RemoteException { super(); } public long add(long a, long b) throws RemoteException { return a + b; public long sub(long a, long b) throws RemoteException { return a - b; public long mul(long a, long b) throws RemoteException { return a * b; public long div(long a, long b) throws RemoteException { return a / b;
Step 3: generate stub and skeleton classes RMI compiler: part of JDK rmic CalculatorImpl Result: CalculatorImpl_Stub.class CalculatorImpl_Skel.class
Step 4: write remote service class import java.rmi.Naming; public class CalculatorServer { public CalculatorServer() { try { Calculator c = new CalculatorImpl(); Naming.rebind("rmi://localhost:1099/CalculatorService", c); } catch (Exception e) { System.out.println("Trouble: " + e); } public static void main(String args[]) { new CalculatorServer();
Step 5: write client program import java.rmi.Naming; import java.rmi.RemoteException; import java.net.MalformedURLException; import java.rmi.NotBoundException; public class CalculatorClient { public static void main(String[] args) { try { Calculator c = (Calculator) Naming.lookup("rmi://localhost/CalculatorService"); System.out.println( c.sub(4, 3) ); System.out.println( c.add(4, 5) ); System.out.println( c.mul(3, 6) ); System.out.println( c.div(9, 3) ); } catch (MalformedURLException murle) { <.. some code here ..> catch (RemoteException re) { <.. some code here ..> catch (NotBoundException nbe) { <.. some code here ..> catch (java.lang.ArithmeticException ae){ <.. some code here ..>
Remarks on parameter passing in RMI Parameters in a single JVM: primitive types: by value object types: “object reference by value” Parameters in RMI: object types: (of course) by value object serialization local reference to a remote object: reference to the proxy