Let's Say Hello To JAVA RMI

What is RMI?

Java Remote Method Invocation (RMI) is a mechanism which allows a java program to invoke methods on an object running in another JVM.

The RMI is used to create distributed applications in Java. That means remote communication between applications can be done using Java RMI.


Let's keep RMI aside for a while and consider the following java classes.

class MyCal{
   int nm;
   public int add(int x,int y){
      return x+y;
   }
   public int sub(int x,int y){
      return x-y;
   }
}

class Main{
   public static void main(String[] args){
      MyCal obj = new MyCal(); //line 1
      int ans = obj.add(4,8); //line 2
   }
}

When the line 1 of Main class is executed, MyCal object will be created in the Heap memory and in the Stack memory there will be the obj reference and the memory address of MyCal object. (look at Figure 1.1)

Figure 1.1

When the line 2 of Main class is executed, it will go to the Stack memory, search for the object named as "obj" and check the memory location (BFFCO) and call the object from Heap memory.
Here both the Stack memory and Heap memory belong to the same Java Virtual Machine(JVM)

What if a program needs to call a method on an object which is located in (heap memory of) a remote machine? (Let's suppose that class MyCal will be in another machine)

  • C👀l... We have Java RMI to get that done.  
_____________________________________________________________

How RMI works?

RMI uses stub and skeleton object for communication with the remote object.


Let's understand the stub and skeleton objects

Stub🔻 

The stub is an object, acts as a gateway for the client side. All the outgoing requests are routed through it. It resides at the client side and represents the remote object. When the caller invokes method on the stub object, it does following tasks:
  1. It initiates a connection with remote JVM.
  2. It writes and transmits (marshals) the parameters to the JVM.
  3. It waits for results.
  4. It reads (unmarshals) the return value or exception.
  5. It finally, returns the value to the caller. 

Skeleton🔻 

The skeleton is an object, acts as a gateway for the server side object. All the incoming requests are routed through it. When the skeleton receives the incoming request, it does the following tasks:  
  1. It reads the parameter for the remote method.
  2. It invokes the method on the actual remote object.
  3. It writes and transmits (marshals) the result to the caller.
(In java 2 SDK, an stub protocol was introduced that eliminates the need for skeletons)



Flow of RMI mechanism

  • Client requests for the remote object reference to naming service
  • Once the naming service locates the server host, RMI registry provides a stub (proxy) of remote object
  • Client can make call using the stub
  • Basically, the request from the stub is sent to the server skeleton which makes the actual request to the remote object
  • Similarly, the server response is sent back through skeleton and stub to the client

Let's build a small RMI program

Steps 
  1. Create the remote interface.
  2. Implement the remote interface.
  3. Create Server application.
  4. Create Client application.
  5. Compile the classes and create stub and skeleton using the rmic tool.
  6. Start registry service by rmiregistry tool.
  7. Start Server application.
  8. Start Client application. 

  • Create the remote interface

interface AddI extends java.rmi.Remote{
   public int add(int x,int y) throws java.rmi.RemoteException;
}

As we need to create a remote interface we should extend Remote class.

  • Implement the remote interface

import java.rmi.*;
import java.rmi.server.*; //where UnicastRemoteObject exists
class AddC extends UnicastRemoteObject implements AddI{
   public AddC() throws RemoteException{
      super();
   }
   public int add(int x,int y){
      return x+y;
   }
}

For providing the implementation of the Remote interface, we need to extend the UnicastRemoteObject class. And as we extend the UnicastRemoteObject class, we must define a constructor that throws RemoteException.

  • Create Server application

import java.rmi.*; //where the Naming class exists
public class Server{
   public static void main(String[] args){
      try{
          AddC stubObj = new AddC();
          Naming.rebind("rmi://localhost/ADD",stubObj);
          System.out.println("Server is running");
      catch(Exception e){
          System.out.println(e);
      }
   }
}
Here we have created an object of AddC class (which implements the AddI interface). Then stubObj (object of AddC) has been bound with the given name("ADD") in registry.  

  • Create Client application

import java.rmi.*; //where the Naming class exists
public class Client{
   public static void main(String[] args){
      try{
          AddI obj = (AddI)Naming.lookup("rmi://localhost/ADD");
          int  ans = obj.add(8,6);
          System.out.println("The answer is "+ans);
      catch(Exception e){
          System.out.println(e);
      }
   }
}

Here we are trying to get the stubObj  by the lookup() method of the Naming class. 
-- Naming.lookup("rmi://localhost/ADD") -- >> This will connect to the localhost and search for any object which is named as "ADD" in registry.

  • Compile the classes

Go to the folder where all the created java classes are in. Then open cmd there and execute the command javac *.java 
Then you will see .class files of those java files

  • Create stub and skeleton using the rmic tool

Next execute the command rmic AddC
Then you will see AddC_Stub.class file

  • Start registry service by rmiregistry tool

Execute the command start rmiregistry

Now run the server then the client and check the output

**As we run the server and the client in the same machine, we use localhostIf you want to access the remote object from another machine, change the localhost to the host name (or IP address) where the remote object is located.

______________________________________________________________

Tip: Understand the concept well. Then you will be able to develop better applications.:octocat::zap:

Comments

Post a Comment

Popular posts from this blog

Preventing CSRF Using Double Submit Cookie Pattern

Preventing CSRF Using Synchronizer Token Pattern

Code Coverage Using Clover