Distributed Systems and Technologies Lab Session On RMI

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 16

DISTRIBUTED SYSTEMS AND

TECHNOLOGIES

Lab Session
on
RMI
RMI
Contents
• Basic concepts
• Examples
• Exercises and Assignments

Asrat M. @ EiT MU 2010 2


Basic Concepts
• The RMI (Remote Method Invocation)
– is an API that provides a mechanism to create
distributed applications in java.
– allows an object to invoke methods on an object
running in another JVM.
– provides remote communication between the
applications using two objects stub and skeleton.
• A remote object is an object whose method
can be invoked from another JVM.

Asrat M. @ EiT MU 2010 3


• stub
– is an object that acts as a gateway for the client side.
– all the outgoing requests are routed through it.
– resides at the client side and represents the remote object.
– when the caller invokes method on the stub object, it does the
following tasks:
• initiates a connection with remote Virtual Machine (JVM),
• writes and transmits (marshals) the parameters to the remote Virtual
Machine (JVM),
• waits for the result
• reads (unmarshals) the return value or exception, and finally,
• returns the value to the caller.
• skeleton
– is an object that 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:
• reads the parameter for the remote method,
• invokes the method on the actual remote object, and
• writes and transmits (marshals) the result to the caller.
Asrat M. @ EiT MU 2010 4
• The RMI system consists of three layers:
– The stub/skeleton layer - client-side stubs (proxies) and server-side skeletons
– The remote reference layer - remote reference behavior (e.g. invocation to a single
object or to a replicated object)
– The transport layer - connection set up and management and remote object tracking
• The application layer sits on top of the RMI system.

Asrat M. @ EiT MU 2010 5


Low-Level Details!
1. The server listens to a port on the server machine.
i. This port is usually an anonymous port that is chosen at runtime by the jvm or the underlying operating
system.
ii. Or, you can say that the server exports itself to a port on the server machine.
2. The client has NO idea on which machine and to which port the server is listening. But, it has a stub
object that knows all these. So, the client can invoke the desired method of the stub.
3. The client invokes the function of the stub.
4. The stub connects to the server's listening port and sends the parameters. The details of this are
given below.
i. The client connects to the server's listening port.
ii. The server accepts the incoming connection and creates a new socket just to handle this single connection.
iii.The old listening port is still there; it waits for the incoming requests from the clients.
iv.The communication between client and server takes place using the newly created socket on the server.
v. With an agreed-upon protocol, they communicate and exchange parameters and results.
vi.The protocol can be JRMP (Java Remote Method protocol) or CORBA-compatible RMI-IIOP (Internet Inter-
ORB Protocol).
5. The method is executed on the server and the result is sent back to the stub.
6. The stub returns the results back to the client as if the stub had executed the function locally.

Asrat M. @ EiT MU 2010 6


• So, that is how it is done.
– Take a critical look at Point 2. The stub knows which host the
server is running and to which port the server is listening. How
is that possible??

• RMI designers have a work-around for this problem known


as the bootstrap problem.
– That is where the RMIRegistry comes in.
– The Registry can be thought of as a service that keeps
(public_name, stub_object) pairs in a hashmap.
– For example,
• if you have a Remote Server object called Scientific_Calculator,
• you can make it available by a public name, "calc".
• For this, you will create a Stub Object at the server machine and
register it with the RMIRegistry so that clients who want to access the
services of the Remote Server object can get the Stub Object from the
Registry.
– For doing these things, we use a class called java.rmi.Naming.

Asrat M. @ EiT MU 2010 7


• Starting from JDK 1.2 the skeleton become
part of the server.
Asrat M. @ EiT MU 2010 8
• If any application performs these tasks, it can
be regarded as a distributed application.
– The application need to locate the remote method
– It needs to provide the communication with the
remote objects, and
– The application need to load the class definitions
for the objects.
• The RMI application have all these features, so
it is called a distributed application.

Asrat M. @ EiT MU 2010 9


Steps writing RMI programs
• Define the remote interfaces
• Implement the server
• Implement the client
• Compile the source files
• Start the Java RMI registry, server, and client,
respectively.

Asrat M. @ EiT MU 2010 10


Examples One Program 03
import java.rmi.registry.LocateRegistry;
Program 01 import java.rmi.registry.Registry;
import java.rmi.Remote; import java.rmi.Naming;
import public class HelloClient02 {
java.rmi.RemoteException; private HelloClient02() {}
public static void main(String[] args)throws Exception {
public interface SayHello extends SayHello sh =
Remote { (SayHello)Naming.lookup("rmi://localhost:1099/SayHello");
public String sayHello(String System.out.println("Got info from server: " ); } }
toWhom) throws Program 04
RemoteException; import java.rmi.registry.Registry; Steps:
} import java.rmi.registry.LocateRegistry; 1. Compile the three classes and the
import java.rmi.RemoteException; interface.
import java.rmi.server.UnicastRemoteObject; 2. Use the RMIC to generate the stub as:-
import java.rmi.Naming; RMIC HelloImpl02
3. On server machine run:- start rmiregistry
public class HelloServer02 {
Program 02 public HelloServer02() {}
and java HelloServer02
4. On the client machine run:- java
import public static void main(String args[]) { HelloClient02
java.rmi.RemoteException; try {
public class HelloImpl02 HelloImpl02 robj = new HelloImpl02();
implements SayHello { SayHello stub = (SayHello) UnicastRemoteObject.exportObject(robj, 0);
public String sayHello(String // Bind the remote object's stub in the registry
toWhom) throws Naming.rebind("rmi://localhost:1099/SayHello",stub);
System.out.println("Hello Server is ready to listen...");
RemoteException { } catch (Exception e) {
return "Hello, " + toWhom; System.err.println("Server exception thrown: " + e.toString());
}} e.printStackTrace(); } } }
Asrat M. @ EiT MU 2010 11
Program 01
import java.rmi.*;
Program Two
Program 03
public interface HelloInterface import java.io.*;
extends Remote { import java.rmi.*;
public String say() throws public class HelloServerx{
RemoteException;
public static void main (String[] args) {
} try {
Program 02 Naming.rebind ("rmi://localhost:1099/Hellox",
import java.rmi.*; new Hellox ("Hello, world!"));
import java.rmi.server.*; System.out.println ("HelloServer is ready.");
public class Hellox extends UnicastRemoteObject
} catch (Exception e) {
implements HelloInterface {
private String message; System.out.println ("HelloServer failed: " + e);
public Hellox (String msg) throws RemoteException { } } }
message = msg; Program 04
} import java.io.*;
public String say() throws RemoteException { import java.rmi.*;
return message; public class HelloClientx{
} public static void main (String[] args) {
} try {
Steps: HelloInterface hello = (HelloInterface)
1. Compile the three classes and the interface. Naming.lookup ("rmi://localhost:1099/Hellox");
2. Use the RMIC to generate the stub as:- rmic System.out.println (hello.say());
Hello } catch (Exception e) {
3. On server machine run:- start rmiregistry and
java HelloServerx System.out.println ("HelloClient failed: " + e);
4. On the client machine run:- java HelloClientx Asrat M. @ }EiT} MU
} 2010 12
Example Three
Program 01 Program 03
import java.rmi.Remote; import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.rmi.Naming;
public interface Calc extends
Remote { public class CalcImpl extends UnicastRemoteObject
implements Calc {
public int add(int i, int
public CalcImpl()throws RemoteException {
j)throws RemoteException; }
super(); }
Program 02 public int add(int i,int j)throws RemoteException {
import java.rmi.Naming; return i+j; }
public class CalcClient { public static void main(String[] args)throws Exception {
public static void main(String[] CalcImpl c=new CalcImpl();
args) throws Exception { Naming.rebind("rmi://localhost:1099/Calc",c); } }
Calc c=(Calc)Naming.lookup
("rmi://localhost:1099/Calc");
System.out.println(c.add(3,4)); }}
Steps:
1. Compile the three classes.
2. Use the RMIC to generate the stub as:- RMIC CalcImpl {two files CalcImpl_Stub.class and
CalcImpl_Stub.java are created}
3. On server machine run:- start rmiregistry and java CalcImpl
4. Asrat M. @ EiT MU 2010
On the client machine run:- java CalcClient 13
Program 02
import java.rmi.RemoteException;
public class PaymentImpl implements Payment {
public double calculatePayment(double principal, double annRate, int years)
throws RemoteException {
double monthlyInt = annRate / 12;

Example Four double monthlyPayment = (principal * monthlyInt)


/ (1 - Math.pow(1/ (1 + monthlyInt), years * 12));
return format(monthlyPayment, 2);
}
public double format(double amount, int places) {
double temp = amount;
temp = temp * Math.pow(10, places);
temp = Math.round(temp);
temp = temp/Math.pow(10, places);
return temp;
Program 01 } }
import java.rmi.Remote; Program 03
import java.rmi.registry.Registry;
import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
public interface Payment extends Remote {
import java.rmi.server.UnicastRemoteObject;
public double calculatePayment(double public class Server {
principal, double annualRate, int terms) public Server() {}
public static void main(String args[]) {
throws RemoteException; } try {
PaymentImpl robj = new PaymentImpl();
Payment stub = (Payment) UnicastRemoteObject.exportObject(robj, 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("rmi://localhost:1099/Payment", stub);
System.out.println("Mortgage Server is ready to listen... ");
} catch (Exception e) {
System.err.println("Server exception thrown: " + e.toString());
e.printStackTrace();
}
} }

Asrat M. @ EiT MU 2010 14


Program 04
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private static Payment stub = null;
private Client() {}
public static void main(String[] args) {
double payment, principal = 80000;
double annualInterest = .065;
int years = 15;
try { Registry reg = LocateRegistry.getRegistry();
On the server side
stub = (Payment) reg.lookup("rmi://localhost:1099/Payment");
} catch (Exception e) {
• Compile Payment.java
//System.err.println("Client exception thrown: " + e.toString()); PaymentImpl.java Server.java
//e.printStackTrace(); }
if (args.length == 3) { • Compile the PaymentImpl.java
try { principal = Double.parseDouble(args[0]); as
annualInterest = Double.parseDouble(args[1]);
years = Integer.parseInt(args[2]); } – rmic PaymentImpl
catch (Exception e) {
System.out.println("Wrong input " + e.getMessage() ); • Start the RMI Registry as
System.exit(0); } – start rmiregistry
print(principal, annualInterest, years);
} else { • Run/start the server as
System.out.println("Usage: java Client principal annualInterest years ");
System.out.println("\nFor example: java Client 80000 .065 15 ");
– java Server
System.out.println("\nYou will get the output like the following: \n");
print(principal, annualInterest, years);
On the client side
} }
System.exit(0); • First make sure that
public static void print(double pr, double annRate, int years){ Payment.class and
double mpayment = 0;
try {
PaymentImpl.class are
mpayment = stub.calculatePayment(pr, annRate, years); accessible.
}catch(Exception e) {
//System.out.println("Remote method exception thrown: " + e.getMessage());} • Run/start the client as
System.out.println("The principal is $" + (int)pr); – java Client
System.out.println("The annual interest rate is " + annRate*100 +"%");
System.out.println("The term is " + years + " years");
System.out.println("Your monthly payment is $" + mpayment); } }

Asrat M. @ EiT MU 2010 15


Projects
• Will be given separately.

Asrat M. @ EiT MU 2010 16

You might also like