Java RMI (Remote Method Invocation)

You might also like

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 31

Java RMI

(Remote Method Invocation)


In the Good Old Days...

Only local objects existed

My Machine

My Object
Today’s World...
Network and Distributed Objects

My Machine Remote
Machine
Local
Remote
Objects
Objects
Introduction
 Remote Method Invocation (RMI) provides a
framework for building distributed Java
systems.

 Using RMI, a Java object on one system can


invoke a method in an object on another system
on the network.
RMI Basics
 RMI is the Java Distributed Object Model for
facilitating communications among distributed objects.
 RMI is a higher-level API built on top of sockets.
 Socket-level programming allows you to pass data
through sockets among computers.
 RMI enables you also to invoke methods in a remote
object.
 Remote objects can be manipulated as if they were
residing on the local host.
 The transmission of data among different machines is
handled by the JVM transparently.
How Does RMI Work?
 All the objects you have used before this chapter are
called local objects. Local objects are accessible only
within the local host.
 Objects that are accessible from a remote host are
called remote objects. For an object to be invoked
remotely, it must be defined in a Java interface
accessible to both the server and the client.
 Furthermore, the interface must extend the
java.rmi.Remote interface.
 java.rmi.Remote is a marker interface that contains no
constants or methods. It is used only to identify remote
objects.
RMI architecture
The key components of the RMI architecture
 Server object interface: A subinterface of java.rmi.Remote
that defines the methods for the server object.
 Server class: A class that implements the remote object
interface.
 Server object: An instance of the server class.
 RMI registry: A utility that registers remote objects and
provides naming services for locating objects.
 Client program: A program that invokes the methods in the
remote server object.
 Server stub: An object that resides on the client host and serves as a
surrogate for the remote server object.
 Server skeleton: An object that resides on the server host and
communicates with the stub and the actual server object.
RMI works as follows:
 (1) A server object is registered with the RMI
registry.
 (2) A client looks through the RMI registry for
the remote object.
 (3) Once the remote object is located, its stub is
returned in the client.
 (4) The remote object can be used in the same
way as a local object. Communication between
the client and the server is handled through the
stub and the skeleton.
Stub and Skeleton
 The stub and the skeleton are automatically generated.
 The stub resides on the client machine. It contains all the
reference information the client needs to know about the
server object.
 When a client invokes a method on a server object, it
actually invokes a method that is encapsulated in the stub.
 The stub is responsible for sending parameters to the server
and for receiving the result from the server and returning it
to the client.
 The skeleton communicates with the stub on the server side.
 The skeleton receives parameters from the client, passes
them to the server for execution, and returns the result to the
stub.
Passing Parameters
 When a client invokes a remote method with parameters,
passing the parameters is handled by the stub and the
skeleton.
 Obviously, invoking methods in a remote object on a server
is very different from invoking methods in a local object on
a client, since the remote object is in a different address
space on a separate machine.
 Stubs
 marshals argument data (serialization) and sends it in a stream
across the network
 unmarshals results data (deserialization)

 Skeletons (not reqd w/Java 2)


 unmarshals argument data/the stream into an object.
 marshals results data
Implementation Details

 The packages used in the implementation of an RMI


client–server application are java.rmi ,
java.rmi.server and java.rmi.registry
 The basic steps are listed below.

12
The basic steps
 Create the interface.
 Define a class that implements this interface.
 Create the server process.
 Create the client process.

13
1. Create the interface
 This interface should import package java.rmi
and must extend interface Remote , which is a
‘tagging’ interface that contains no methods.
 The interface definition for our example must
specify the signature for method getGreeting,
which is to be made available to clients.
 This method must declare that it throws A
RemoteException

import java.rmi.*;
public interface Hello extends Remote {
public String getGreeting() throws
RemoteException;
}
2. Define a class that implements this interface
 The implementation file should import
packages java.rmi and java.rmi.server .

 The implementation class must extend class


RemoteObject or one of RemoteObject ’s
subclasses.

 In practice, most implementations extend


subclass UnicastRemoteObject , since this
class supports point-to-point communication
using TCP streams.
15
 The implementation class must also implement
our interface Hello , of course, by providing an
executable body for the single interface method
getGreeting.

 In addition, we must provide a constructor for


our implementation object (even if we simply
give this constructor an empty body, as below).

 Like the method(s) declared in the interface, this


constructor must declare that it throws a
RemoteException .

16
import java.rmi.*;
import java.rmi.server.*;

public class HelloImpl extends UnicastRemoteObject


implements Hello
{
public HelloImpl() throws RemoteException
{
//No action needed here.

}
public String getGreeting() throws RemoteException
{
return ("Hello there!");
}
}

17
3. Create the server process
 The server creates object(s) of the above
implementation class and registers them with a naming
service called the registry
 The registry is implemented by a class called Naming
and an application called rmiregistry. The rmiregistry
application must be running on a host before you start a
Java program that wants to advertise in the registry.

 It does this by using static method rebind of class


Naming (from package java.rmi ).
 This method takes two arguments:
 a string that holds the name of the remote object as a
URL with protocol rmi ;
 a reference to the remote object (as an argument of type
Remote ).
18
 The method establishes a connection between
the object’s name and its reference.
 Clients will then be able to use the remote
object’s name to retrieve a reference to that
object via the registry.
 The URL string, as well as specifying a
protocol of rmi and a name for the object,
specifies the name of the remote object’s host
machine.
 For simplicity sake, we shall use localhost
(which is what RMI assumes by default
anyway).

 The default port for RMI is 1099, though we


can change this to any other convenient port if
19
import java.rmi.*;
public class HelloServer
{
private static final String HOST = "localhost";
public static void main(String[] args)
throws Exception
{
//Create a reference to an
//implementation object…
HelloImpl temp = new HelloImpl();
//Create the string URL holding the
//object's name…

String rmiObjectName = "rmi://" + HOST + "/Hello";


//'Bind' the object reference to the name…
Naming.rebind(rmiObjectName,temp);
//Display a message so that we know the process
//has been completed…
System.out.println("Binding complete…\n");
}
} 20
4. Create the client process
 The client obtains a reference to the remote
object from the registry.
 It does this by using method lookup of class
Naming , supplying as an argument to this
method the same URL that the server did when
binding the object reference to the object’s name
in the registry.
 Since lookup returns a Remote reference, this
reference must be typecast into an Hello
reference ( not an HelloImpl reference!).
 Once the Hello reference has been obtained, it
can be used to call the solitary method that was
made available in the interface.
21
import java.rmi.*;
public class HelloClient {
private static final String HOST = "localhost";
public static void main(String[] args)
{
try {
//Obtain a reference to the object from the registry and typecast it into the appropriate
type…
Hello greeting = (Hello)Naming.lookup("rmi://" + HOST + "/Hello");
//Use the above reference to invoke the remote object's method…
System.out.println("Message received: " + greeting.getGreeting());
} catch(ConnectException conEx)
{
System.out.println( "Unable to connect to server!");
System.exit(1);
} catch(Exception ex)
{
ex.printStackTrace();
System.exit(1);
}
}
22
}
Compilation and Execution

1. Compile all files with javac.


 javac Hello.java
 javac HelloImpl.java
 javac HelloServer.java
 javac HelloClient.java

23
 [Note that, before Java SE 5, it was necessary
to compile the implementation class (yes,
compile a .class file!) with the rmic compiler
thus:
 rmic HelloImpl
 This would generate both a stub file and a
skeleton file. However, this stage is no longer
required.]
2. Start the RMI registry
rmiregistry
 When this is executed, the only indication that
anything has happened is a change in the command
window’s title.

25
3. Open a new window and run the server
From the new window, invoke the Java
compiler:
java HelloServer

26
4. Open a third window and run the client
Again, invoke the Java compiler:
java HelloClient

27
Example 2
Step 1: Defining the Remote Interface

import java.rmi.*;

public interface SampleServer extends Remote


{
public int sum(int a,int b) throws RemoteException;
}
Step 2: Implement the remote object interface
/* SampleServerImpl.java */
import java.rmi.*;
import java.rmi.server.*;

public class SampleServerImpl extends UnicastRemoteObject


implements SampleServer
{
SampleServerImpl() throws RemoteException
{

}
//Implement the remote methods
public int sum(int a,int b) throws RemoteException
{
return a + b;
}
. . .
Use java.rmi.Naming class to bind the server name to
registry.
public static void main(String args[])
{
try
{
//create a local instance of the object

SampleServerImpl Server = new SampleServerImpl();

//put the local instance in the registry


Naming.rebind("SAMPLE-SERVER" , Server);

System.out.println("Server waiting.....");
}
catch (java.net.MalformedURLException me){
System.out.println("Malformed URL: " + me.toString());
}
catch (RemoteException re) {
System.out.println("Remote exception: " + re.toString());
}
}
Step 3: Develop the client program
import java.rmi.*;
import java.rmi.server.*;

public class SampleClient


{
public static void main(String[] args)
{
//get the remote object from the registry
try
{
String url = "//localhost/SAMPLE-SERVER";
SampleServer remoteObject =(SampleServer)Naming.lookup(url);
System.out.println("Got remote object");
System.out.println(" 5 + 6 = " + remoteObject.sum(5,6) );
}
catch (RemoteException exc) {
System.out.println("Error in lookup: " + exc.toString()); }
catch (java.net.MalformedURLException exc) {
System.out.println("Malformed URL: " + exc.toString()); }
catch (java.rmi.NotBoundException exc) {
System.out.println("NotBound: " + exc.toString());
}
}
}

You might also like