You are on page 1of 5

RMI

Source – HeadFirst-> java; jsp&Servlet; EJB; DesignPattern

RMI in 5 minutes

 Make a Remote Interface - MyRemote implements Remote


 Make a Remote Implementation – MyRemoteImpl implements MyRemote.
o The Real Service. The class with the methods that do the real work. It implements the
remote interface.
 Generate the stubs and skeletons using rmic - %rmic MyRemoteImpl
 Start the RMI registry (in separate terminal) - %rmiregistry
o It's where the user goes to get the proxy [client stub/helper object].
 Start the remote service in another terminal - java MyRemoteImpl

How does the client get the stub object?


 Client does a lookup on the RMI registry using service-name.
o Naming.lookup(“rmi://127.0.0.1/Remote Hello”);
 RMI registry returns the stub object –
o RMI deserialize the stub automatically.
o Client must have the rmic generated stub class[MyRemoteImpl_Stub.class] beforehand
else deserialization will fail.
 Client invokes a method on the stub, as though the stub IS the real service.
RMI - Details

In most applications, when one object calls a method on another, both objects are on the same heap.
i.e. both are running within the same JVM.

JVM can know about references on only its own heap. JVM running in one machine cannot know
anything about different JVM running on same/different machine.

How to invoke a method on an object running on another machine?


We can get information from one machine to another using sockets and IO. We open socket connection
to another machine and get an outputStream and write data to it. So for remote method invocation we
can write our own protocol and when you send data to serverSocket server could parse it, figure out
what you meant, do the work and send back the result on another stream.

Big Pain!!

RMI comes for the rescue. With RMI you call a method on a remote object, but with code that lets you
pretend that you are invoking a method in a local object.

A design for remote method calls Create four things: server, client, skeleton (server helper), stub (client
helper).

Create client and server apps. The server app is the remote service that has an object with the method
that the client wants to invoke.

Create client and server ‘helpers’. They’ll handle all the low-level networking and I/O details so your
client and service can pretend like they’re in the same heap.

Your client object gets to act like it is making remote method calls. But what it’s really doing is calling
methods on a heap-local ‘proxy’ object that handles all the low-level details of Sockets and streams.

 Client helper[stub] pretends to be the service, but it’s just a proxy for the Real Thing.
 Service helper[skeleton] gets the request from the client helper, unpacks it, and calls the
method on the Real Service.
 The Service object IS the Real Service. It’s the object with the method that actually does the real
method work.

How the method call happens?

 Client object calls doBigThing() on the client helper[stub] object.


 Client helper packages up information about the call (arguments, method name, etc.) and ships
it over the network to the service helper[skeleton].
 Service helper[skeleton] unpacks the information from the client helper, finds out which method
to call (and on which object) and invokes the real method on the real service object.

Java RMI gives you the client and service helper objects! --- >>Page-614
Remote Service

Making the Remote Service - A 5 step process

 Make a Remote Interface - MyRemote.java


o This interface defines the remote methods that clients are interested to call.
o Both stub and actual service will implement this. DP Program to the IF
 Make a Remote Implementation - MyRemoteImpl.java
o The Real Service. The class with the methods that do the real work. It implements the
remote interface.
 Generate the stubs and skeletons using rmic - %rmic MyRemoteImpl
o Running rmic against the actual service implementation class spits out two new classes
for the helper objects: MyRemoteImpl_Stub.class and MyRemoteImpl_Skel.class
 Start the RMI registry (rmiregistry) - %rmiregistry
o Run this in a separate terminal.
o It's where the user goes to get the proxy[client stub/helper object].
 Start the remote service - java MyRemoteImpl

Making a Remote Interface

 Extend java.rmi.Remote and declare all methods which client need to call
Remote is a marker interface which has some special meaning for RMI.
 Declare methods must throw a RemoteException
The client calls method on stub and stub does network and IO so its risky. The client has
to acknowledge the risk by handling or declaring the remote exception.
 Be sure arguments and return values are primitives or Serializable
Any arguments to a remote method has to be packaged up and shipped across the
network and that is done through serialization. Same thing with return values.

import java.rmi.*;
public interface MyRemote extends Remote {
public String sayHello() throws RemoteException;
}
This return value[String] is going to be shipped over the wire from the server back to the client,
so it must be Serializable.

Making a Remote Implementation

public class MyRemoteImpl extends UnicastRemoteObject


implements MyRemote{
public String sayHello() {
return “Server says, ‘Hey’”;
}

public static void main (String[] args) {


MyRemote service = new MyRemoteImpl();
Naming.rebind("Remote Hello", service);
}
// more code in class
}

 Implement the Remote interface and all of its methods.


 Extend UnicastRemoteObject
To work as remote service object, your object needs some
functionality related to being remote.
Extending UnicastRemoteObject is one way to achieve this.
 Write a no-arg constructor that declares a RemoteException
UnicastRemoteObject constructor throws a RemoteException
Concept - When class is instantiated it's super class constructor
is called.
If super class constructor throws an Exception you have no choice
but to declare that your constructor also throws an Exception.
 Register the service with the RMI registry
You need to make remote service available to remote clients.
For this Instantiate the remote service (MyRemoteImpl) and put it
to RMI-regitery.
 Naming.rebind("Remote Hello", service);
RMI-regitery must be running before this line of code.
When you bind the service object, RMI swaps the service for the
stub and puts the stub in the registry. That's what the client
need.
Give your service a name (“Remote Hello”) , it is used by clients
to look up the service in the registry.

Run rmic on the remote implementation class - - %rmic MyRemoteImpl

 This will generate two helper class MyRemoteImpl_Stub.class and


MyRemoteImpl_Skel.class.
 rmic must be able to see implementation class so run it from the location
where MyRemoteImpl.class is present. [need to check]

Start the RMI registry (rmiregistry) - %rmiregistry

 From a directory that has access to your classes.

Start the remote service - java MyRemoteImpl


Client

import java.rmi.Naming;
import J_Importent.RMI.Interface.MyRemote;

public class MyRemoteClient {


public static void main (String[] args) {
MyRemote service = (MyRemote) Naming.lookup
("rmi://127.0.0.1/Remote Hello");
String s = service.sayHello();
}
}

Client gets the stub object from rmi-registry using lookup method of Naming by
providing stub name [this is used by service to register stub].

MyRemote service = (MyRemote) Naming.lookup(“rmi://127.0.0.1/Remote Hello”);

 The client always uses the remote implementation as the type of the
service. Programming to the IF.
 Returned object need to be to cast to the interface, since the lookup
method returns type Object.
 Returned stub object from RMI registry is deserialized automatically.
VVI - You must have stub object[grnerated by rmic] at client or the
stub [returned by registery] will not be deserialized, and whole
things blows up.
 Client invokes a method on the stub, as though the stub IS the real service

Remember –

 The client JVM needs the stub class, but the client never refers to the
stub class in code. The client always uses the remote interface, as though
the remote interface WERE the actual remote object.
Stub is required to deserialized the stub obtained from RMI-
registery.
 Server needs both the Stub and Skeleton classes.
It needs the stub class because remember, the stub is substituted for
the real service, when the real service is bound to the RMI registry.

RMI Uses

 EJB-based Applications as EJB uses RMI!


 Jini technology is based on RMI.
 B-to-B, e-commerce backends, running on J2EE technology.

You might also like