Java
RMI:
The
Java Remote Method Invocation (RMI) system allows an object running
in one Java virtual machine to invoke methods on an object running in
another Java
virtual
machine. RMI provides for remote communication between programs
written in the Java programming language.
only
supports making calls from one JVM to another. The protocol
underlying this Java-only implementation is known as Java Remote
Method Protocol (JRMP).
In
order to support code running in a non-JVM context, a CORBA version
was later developed.
RMI
provides the mechanism by which the server and the client communicate
and pass information back and forth
Client
-->Stub-->RRL(remote reference Layer)-->Transport Layer
Server<--Skeleton<--RRL
<--Transport Layer
Stub
is the proxy of the Remote object at client side.
Sending
objects from client to server and from server to client happens with
marshaling mechanism
which
actually serializes the objects and adds header to that and sends, at
the receiving end Unmarshaling happens which actually re-creates the
object(de-serialization) .
When
a client communicates with the Server object it opens a socket for
the communication
Once
the server creates the Remote Object, it places the Remote object
into RMI registry with the unique bind name.
//Exports
the remote object to make it available to receive incoming calls,
using the particular supplied port
Hello
stub =
(Hello) UnicastRemoteObject.exportObject(server,
0);
Registry
registry =
LocateRegistry.getRegistry();
//Binds
a remote reference to the specified
name
in this registry.
registry.bind("Hello",
stub);
at
this point Server becomes client and Registry becomes Server and
again Remote call happens between Server to Registry to store remote
Object into Registry.
Client
uses this bind name to look up for, to get the respective remote
object and calls the Remote methods on that.
Registry
registry =
LocateRegistry.getRegistry();
//
Returns the remote reference bound to the specified name in this
registry
Hello
response =
(Hello) registry.lookup("Hello");
RMI
Implementation
Write
an Interface:
It
contains all Business methods invoked by the client
The
interface must extend Remote interface of RMI
all
the methods must throw RemoteException
Write
an Implementation Class :
Implement
the above interface and extend the UnicastRemoteObject class
if
not possible(i.e., if the class already extending some other class)
need to export object
Server
program :
Create
the instance of the implementation class
place
remote object into RMI Registry
ie.,
Naming.bind("bindName", object); (or)
Naming.rebind("bindName",
object);[it is for localhost]
Naming.rebind("machineName:port:bindName",);
Client program:
Fetch
the Remote object
Naming.lookup("rmi://machineNme:port/bindName");
Downcast
it and invoke the method
Finally,
the client invokes the sayHello method on the remote object's stub,
which causes the following actions to happen:
- The client-side runtime opens a connection to the server using the host and port information in the remote object's stub and then serializes the call data.
- The server-side runtime accepts the incoming call, dispatches the call to the remote object, and serializes the result (the reply string ) to the client.
- The client-side runtime receives, deserializes, and returns the result to the caller.
Code:
Interface
:
package
com.awf.org;
import
java.rmi.Remote;
import
java.rmi.RemoteException;
public
interface
Hello extends
Remote{
String
sayHello(String clientName)
throws
RemoteException;
}
Implementing
Class and Server Program:
package
com.awf.org;
import
java.rmi.AlreadyBoundException;
import
java.rmi.RemoteException;
import
java.rmi.registry.LocateRegistry;
import
java.rmi.registry.Registry;
import
java.rmi.server.UnicastRemoteObject;
/**
*
*this
class has Interface implementation and Server program i.e.,
bind related stuff
*/
public
class
Server implements
Hello {
public
Server() {
}
@Override
public
String sayHello(String clientName)
throws
RemoteException {
return
"Hello "
+ clientName
+ "...!!!";
}
public
static
void
main(String args[])
{
Server
server =
new
Server();
try
{
//
Exports the remote object to make it available to receive
//
incoming calls, using the particular supplied port
Hello
stub =
(Hello) UnicastRemoteObject.exportObject(server,
0);
Registry
registry =
LocateRegistry.getRegistry();
//
Binds a remote reference to the specified name in this registry.
registry.bind("Hello",
stub);
System.out.println("Server
started...!");
}
catch
(RemoteException e)
{
e.printStackTrace();
}
catch
(AlreadyBoundException e)
{
//
this exception occurs if we try to bind the object with the same
//
bindName using registry.bind() method
//
it can be avoided using Naming.rebind("bindName",
object);it
//
actually replaces the object
e.printStackTrace();
}
}
}
//
We can also write a server class as below
public
class Server extends
UnicastRemoteObject implements
Hello {
}
in
another class
Server
rmiDemoObj = new
Server();//throws RemoteException
Naming.rebind("RMIDemo",
rmiDemoObj);//
throws MalformedURLException
Client
Class:
package
com.awf.org;
import
java.rmi.NotBoundException;
import
java.rmi.RemoteException;
import
java.rmi.registry.LocateRegistry;
import
java.rmi.registry.Registry;
public
class
Client {
public
static
void
main(String[] args)
{
try
{
Registry
registry =
LocateRegistry.getRegistry();
//
Returns the remote reference bound to the specified name in this
//
registry
Hello
response =
(Hello) registry.lookup("Hello");
System.out.println("Server
response ::"
+
response.sayHello("Supreme"));
}
catch
(RemoteException | NotBoundException e)
{
e.printStackTrace();
}
}
}
Running
RMI application:
a)Compile
interface, Implementation class, server, client classes using javac
b)start
RMI Registry using command (start rmiregistry)
c)Run
server program using below command
the
below command sets the code base which downloads the stub
dinamically and client uses this stub to call remote methods.
It
opens new command prompt to display execution result of Server
start
java -classpath C:\MyJavaWorld\MyExperiments\RMIApp\bin\
-Djava.rmi.server.codebase=C:\MyJavaWorld\MyExperiments\RMIApp\bin\
com.awf.org.Server
d)open
another command prompt to run the client program.
Example:
In
eclipse create project RMIApp
under
source create package com.awf.org
create
Above classes[Hello interface, Server,Client Classes]
a)if
java files are created using eclise, class files will be there under
bin folder of the project bin/com/awf/org/<classfiles>
b)open
a command prompt
C:\Users\IBM_ADMIN>cd
C:\MyJavaWorld\MyExperiments\RMIApp\bin
C:\MyJavaWorld\MyExperiments\RMIApp\bin>start
rmiregistry
[Result
:This opens a new CMD to run RMI Registry]
c)C:\MyJavaWorld\MyExperiments\RMIApp\bin>start
java -classpath C:\MyJavaWorld\MyE
xperiments\RMIApp\bin\
-Djava.rmi.server.codebase=C:\MyJavaWorld\MyExperiments\R
MIApp\bin\
com.awf.org.Server
[Result:
opens a new command prompt and prints Server output below]
Server
started...!
d)in
new CMD to run Client program
C:\MyJavaWorld\MyExperiments\RMIApp\bin>java
com.awf.org.Client
Server
response ::Hello Supreme...!!!
Note:
Prior to J2SE 5.0 release Step c) needs to be replaced with the below
The
below rmic commad is used for compiling Remote Implementation
class[here its Server. We can write Implementation class and Server
class separately also]
C:\MyJavaWorld\MyExperiments\RMIApp\bin>rmic
com.awf.org.Server
[Result:
Generates the Stub class Server_stub.class]
C:\MyJavaWorld\MyExperiments\RMIApp\bin>
java com.awf.org.Server
Server
started...!




No comments:
Post a Comment