RMI Application Step by Step Explanation

RMI Application Coding

Note: But before going into this tutorial, it is advised to read RMI tutorial and also architecture.

A typical RMI application includes four programs.

  1. Remote interface: Write an interface that should extend an interface called Remote from java.rmi package.
  2. Implementation program: Write a concrete class which extends UnicastRemoteObject and implements the above remote interface.
  3. Server Program: Write a server program to register the object with RMI registry.
  4. Client program: Write a client program to request for object and method invocation.

For communication, the other supporting programs are stub, skeleton and RMI registry. To explain better, let us jump into a simple application and explain in detail. Then we will go to a bigger bank application with database access using collections.

The application is of interest calculation. The client sends principle, time and rate of interest to server. Server calculates the interest amount and the total amount to be paid to clear the complete debt.

1. Remote interface
File Name: Interest.java

This is a simple interface with some abstract methods and extending Remote interface.

import java.rmi.*;
public interface Interest extends Remote
{
  public abstract int getInterest(int principle, int time, int rate) throws RemoteException;
  public abstract String getTotal() throws RemoteException;
}

To look, it is a simple interface program with two abstract methods. Let us see the guidelines or rules of writing the interface.

RMI Guidelines for interface file

  • The Interest interface should extend Remote interface.
  • The interface Interest is known as remote interface as it extends interface java.rmi.Remote.
  • All the methods involved in communication should be written in the remote interface. It is a contract between client and server to use only these methods included in the remote interface. That is, client should invoke only these remote methods on the server.
  • All the methods should throw java.rmi.RemoteException.
  • The methods parameters are used by the client to send data to server and the return type is used by the server to send data to client.
  • In file distribution, this file is to placed both on client and server (this is discussed in RMI Stepwise Compilation Execution Distribution).

2. Implementation Program
File Name: InterestImpl.java

This is simple concrete (non-abstract) program where we implement (override) all the abstract methods of the remote interface.

import java.rmi.*;                  // for RemoteException
import java.rmi.server.*;           // for UnicastRemoteObject
public class InterestImpl extends UnicastRemoteObject implements Interest
{
  int interest, principle;
  public InterestImpl() throws RemoteException
  {
    super();
  }
  public int getInterest(int principle, int time, int rate) throws RemoteException
  {
    this.principle=principle;
    interest = (principle*time*rate)/100;
    return interest;
  }
  public String getTotal() throws RemoteException
  {
    String str = "Pay Rs." +(principle+interest)+ " to clear the debt completely"; 
    return str;
  }
}

RMI Guidelines for implementation file

  • The implementation file should extend an abstract class called java.rmi.server.UnicastRemoteObject and implement the interface Interest.
  • The UnicastRemoteObject makes the server object exportable to the client system through Remote reference layer (here, client gets a reference of remote object of server, or to say, server passes the remote object by reference (pass-by-reference) to client).
  • A default constructor is included for more clarity and infact it is not required as one is created by JVM implicitly calling super class constructor.
  • All the methods of remote interface should be overridden here.
  • All the methods and constructor should throw java.rmi.RemoteException.
  • In file distribution, this file is placed on server-side.

3. Server Program
File Name: InterestServer.java

Do not expect much code here. Do not imagine a gigantic Servlet code here. It is named server program by me as this code is executed on the server side and a program is necessary for this purpose.

This program creates a remote object, links with an alias name and binds with the RMI registry, linked to RMI runtime mechanism.

import java.rmi.*;
public class InterestServer
{
  public static void main(String args[]) throws Exception
  {
    Interest i1= new InterestImpl();
    Naming.rebind("roses", i1);  // roses is alias name for i1 and is used later by the client
    System.out.println("Server is ready for remote invocations by client");
  }
}

RMI Guidelines for server file

  • The remote interface object i1 is returned by the implementation program constructor, new InterestImpl(). i1 is known as remote object in RMI technology.
  • RMI uses a naming service (like the one JNDI) where an alias name is maintained and this alias name should be known to client to invoke the remote method. It can be compared to <url-pattern> in Servlets. The naming service is represented by a class called java.rmi.Naming. The rebind() method of Naming class binds the object i1 along alias name with the RMI registry. Alias name "roses" refers the object i1 on server side. Object i1 RMI registry is connected internally with the Remote reference layer.
  • Just a message is printed for clarity after binding.
  • In file distribution, this file is placed on server side.

In this and next client code, the main() method throws Exception to make code simple without catching each checked exception thrown by the methods. This will be shown in next Bank application with database access along setting with RMI security manager.

4. Client Program
File Name: InterestClient.java

This program obtains a reference of the remote object of server and invokes remote methods.

import java.rmi.*;
public class InterestClient 
{
  public static void main(String args[]) throws Exception
  {
    // Object obj1 = Naming.lookup("roses");
    // Interest i2 = (Interest) obj1;
                                      // the above statements can coded as one as follows
    Interest i2 = (Interest) Naming.lookup("roses");

    int interestAmount = i2.getInterest(5000, 3, 12);  
    System.out.println("Pay interest Rs." + interestAmount);

    String str1 = i2.getTotal();
    System.out.println(str1);
                                      // with remote referene i2, you can invoke any number times
    System.out.println("Pay interest Rs."+i2.getInterest(6500, 2, 10));
    System.out.println(i2.getTotal());
 }
}

Code Explanation

The i2 on client side is a reference object that refers i1 on server side. That is, i1 on the server is known as remote object. Now i2 refers the remote object. Every method we call with i2 like i2.getInterest(5000, 3, 12), becomes i1.getInterest(5000, 3, 12) on the server. The remote object i1 invokes the remote method getInterest(5000, 3, 12) on the server and returns the return value to local variable interestAmount. Every operation you do on i2 on client side, will be executed on the server with object i1. i2 is the reference (replica) of i1. Observe, i2 and i1 exists on two different systems(this is specialty of RMI). i2 and i1 communicates each other and is known as object communication. This is how remote method invocation and object communication works.

Interest i2 = (Interest) Naming.lookup(“roses”);

It can be written like this also.

Interest i2 = (Interest) Naming.lookup(“rmi://127.0.0.1:1099/roses”);

The above statement is written keeping in view that the same system (with IP address 127.0.0.1) is treated both as a client and server (with two DOS prompts opened). It uses the default port number 1099. If the server is different system which is true in realtime practice, replace 127.0.0.1 with the actual address of the server.

For compilation, execution and file distribution of the above 4 program refer RMI Stepwise Compilation Execution Distribution.

Leave a Comment

Your email address will not be published.