You are on page 1of 7

Introduction to Remote Method Invocation (RMI)

by Tung Tran

Introduction
RMI allows object on one system to call a method in an object somewhere else on the
network, and even pass objects in and out to that remote object. RMI is a java-specific
version of a CORBA framework. It is built on top of sockets. Sockets, however, only
allow data passing to the server.

Sample program using RMI


This example will calculate Easter date with given year.

The calculation is done on the RMI remote server.

With stub and skeleton classes, client can use all the methods
put_Year, CaculateEaster, get_Year, get_Month, get_Day from a
remote server just like they are right on client machine. This is
done by RMI and its object communication through sockets.

CLIENT

CalculateEasterClient.class
CalculateEasterInterface.class put
CalculateEasterServer_Stub.class _Y e
CalculateEasterServer_Skel.class C al c ar
java.policy u la t
e Ea SERVER
st er
get
get Y e_ CalculateEasterServer.class
_ Mo a r CalculateEasterInterface.class
get nth CalculateEasterServer_Stub.class
_D a CalculateEasterServer_Skel.class
y java.policy

Files needed
// server
CalculateEasterServer.java

With methods:

- put_Year
- get_Year
- get_Month
- get_Day
- CalculateEaster

The interface to RMI remote server.

// interface
CalculateEasterInterface.java

The client who is using methods from the server to get the Easter date given the year to
server.

// client
CalculateEasterClient.java

Compile the codes

Compile the interface


>javac CalculateEasterInterface.java

Compile the server


>javac CalculateEasterServer.java

Build stub and skeleton files


>rmic CalculateEasterServer.java

Compile the client


>javac CalculateEasterClient.java

Start rmiregistry, 2 more files are generated: CalculateEasterServer_Stub.class and


CalculateEasterServer_Skel.class
>start rmiregistry

Create a file called java.policy. This file grants socket permission to the server. It
contains these lines:

grant
{
permission java.net.SocketPermission "*:1024-65535","connect,accept,resolve";
permission java.net.SocketPermission "*:1-1023","connect,resolve";
};

Run the server


>java -Djava.security.policy=java.policy CalculateEasterServer

Run the client


>java -Djava.security.policy=java.policy CalculateEasterClient localhost
Note:
• If server is a remote server, localhost is changed to server host name.
• Compiled java files needed by server are:
CalculateEasterServer.class
CalculateEasterInterface.class
CalculateEasterServer_Stub.class
CalculateEasterServer_Skel.class
and by client are:
CalculateEasterClient.class
CalculateEasterServer_Stub.class
CalculateEasterServer_Skel.class

Make sure these files are in classpath if they are not in the same directory.

References

http://www.javacoffeebreak.com/articles/javarmi/javarmi.html

Beginning ATL3COM Programming from Wrox publisher.

Just Java 2, Fourth Edition, Peter Van der Linden, The Sun Microsystems Press.
These are files that can be found in CalEaster.jar

// CalculateEasterClient.java

import java.rmi.*;
import java.rmi.Naming;
import java.io.*;

//
//
// CalculateEasterClient
//
//// References:
// - http://www.javacoffeebreak.com/articles/javarmi/javarmi.html
// - Beginning ATL3COM Programming from Wrox publisher
//
public class CalculateEasterClient
{
public static void main(String args[]) throws Exception
{
// Check for hostname argument
if (args.length != 1)
{
System.out.println ("Syntax - CalculateEasterClient host");
System.exit(1);
}

// Assign security manager


if (System.getSecurityManager() == null)
{
System.setSecurityManager(new RMISecurityManager());
}

// Call registry for CalculateEasterInterface


CalculateEasterInterface calculateEasterInterface = (CalculateEasterInterface) Naming.lookup
("rmi://" + args[0] + "/CalculateEasterInterface");

BufferedReader din = new BufferedReader (new InputStreamReader(System.in));

for (;;)
{
System.out.println ("1 - Calculate Easter");
System.out.println ("2 - Exit"); System.out.println();
System.out.print ("Choice : ");

String line = din.readLine();


Integer choice = new Integer(line);

int value = choice.intValue();

switch (value)
{
case 1:
System.out.print ("Enter Year : ");
line = din.readLine();System.out.println();
choice = new Integer (line);
calculateEasterInterface.put_Year(choice.intValue());
calculateEasterInterface.CalculateEaster();
// Call remote method
System.out.println ("Easter : " + calculateEasterInterface.get_Month() +
"/" + calculateEasterInterface.get_Day() + " in " +
calculateEasterInterface.get_Year());

break;
case 2:
System.exit(0);
default :
System.out.println ("Invalid option");
break;
}
}
}

import java.math.*;
import java.rmi.*;
import java.rmi.server.*;
import java.lang.Number;

//
//
// CalculateEasterServer.java
//
// Server for a RMI service that calculates Easter date
// References:
// - http://www.javacoffeebreak.com/articles/javarmi/javarmi.html
// - Beginning ATL3COM Programming from Wrox publisher
//
public class CalculateEasterServer extends UnicastRemoteObject implements
CalculateEasterInterface
{
private static int m_Year;
private static int m_Month;
private static int m_Day;

public CalculateEasterServer () throws RemoteException


{
m_Year = -1;
m_Month = -1;
m_Day = -1;
}

// Set the year


public void put_Year ( int year ) throws RemoteException
{
m_Year = year;
}

// Calculate Easter date


public int get_Year ( ) throws RemoteException
{
return m_Year;
}

public int get_Month ( ) throws RemoteException


{
return m_Month;
}
public int get_Day ( ) throws RemoteException
{
return m_Day;
}
// this code is from Beginning ATL3COM, Wrox Publisher, Chapter3
public void CalculateEaster() throws RemoteException
{
// first, check we have a year set, and that
// it is within the range for the calculation
if (m_Year < 326 || m_Year > 4099)
return;

int first = m_Year / 100; // first two digits


int div19 = m_Year % 19; // remainder when divided by 19
// find the date of the PFM (Paschal Full Moon)
int temp = (first - 15) / 2 + ((first > 26) ? -1 : 0) +
((first > 38) ? -1 : 0) + 202 - 11 * div19;
if(first == 21 || first == 24 || first == 25 ||
first == 33 || first == 36 || first == 37)
temp += -1;

temp %= 30;

int ta = temp + ((temp == 29) ? -1 : 0) +


((temp == 28 && div19 > 10) ? -1 : 0) + 21;

// find the next sunday


int tb = (ta - 19) % 7;
temp = (40 - first) % 4;
int tc = temp - ((temp > 1) ? -1 : 0) - ((temp == 3) ? -1 :
0);

temp = m_Year % 100;


int td = (temp + temp / 4) % 7;
int te = ((20 - tb -tc -td) % 7) + 1;

m_Day = ta + te;

// find the month


if(m_Day > 61)
{
m_Day -= 61;
m_Month = 5;
}
else if (m_Day > 31)
{
m_Day -= 31;
m_Month = 4;
}
else
{
m_Month = 3;
}

public static void main ( String args[] ) throws Exception


{
// Assign a security manager, in the event that dynamic classes are loaded
if (System.getSecurityManager() == null)
System.setSecurityManager ( new RMISecurityManager() );

// Create an instance of our CalculateEasterServer ...


CalculateEasterServer svr = new CalculateEasterServer();

// ... and bind it with the rmi registry


Naming.bind ("CalculateEasterInterface", svr);

System.out.println ("Service bound....");


}
}

//
// References:
// - http://www.javacoffeebreak.com/articles/javarmi/javarmi.html
// - Beginning ATL3COM Programming from Wrox publisher
//
// CalculateEasterInterface.java
//
import java.rmi.*;
public interface CalculateEasterInterface extends java.rmi.Remote
{
// put_Year method to input the year you want to know the date of Easter
public void put_Year ( int year ) throws RemoteException;

// Easter year
public int get_Year ( ) throws RemoteException;

// Easter month
public int get_Month ( ) throws RemoteException;

// Easter day
public int get_Day ( ) throws RemoteException;

// calculate Easter date from given year


public void CalculateEaster ( ) throws RemoteException;
}

java.policy

grant
{
permission java.net.SocketPermission "*:1024-65535",
"connect,accept,resolve";
permission java.net.SocketPermission "*:1-1023",
"connect,resolve";
};

You might also like