Você está na página 1de 67

Remote Method

Invocation
Introduction
What is Remote Method
Invocation?
Remote method invocation allows objects
residing in one JVM execute methods of objects
residing in another JVM.
The two JVMs can be in the same machine or
executing on different machines located in a
network.
The object executing a remote method does so
as if the remote object was present locally (i.e.
accessible through the local classpath.
Why RMI?
To understand this a review of the traditional approach to
invoking remote methods is warranted:
Traditional method of doing this was by use of Stream Sockets.
Stream sockets can be used to pass primitive data types or
objects(provided they implement the Serializable interface)
between two hosts on a network.
Stream sockets always passed data by value. That is copies of
objects were passed back and forth to effect communication.
Why RMI?
Now imagine a client server scenario, in which a
client wants to update an Account object present
on the server.
The client will typically open a connection to the
server and request the object by name.
The server will then send a copy of this object to the
client through an ObjectOutputStream.
The client will receive this object, update the object
and send the modified object to the server.
The server in turn will replace the server object with
the new object received from the client.
Why RMI?
If many clients are requesting updates on objects residing on the
server, the number of object copies that travel on the network
increases proportionally.
The point is that since Objects are passed by value, a copy of the object
is sent to the requesting client
Thus any modification made on the passed object is not reflected on the
server unless the modified object is passed back.
This increases network traffic and can have serious implications on the
network band-width.
For more complex operations like querying a database located on the
server the performance implications will be extremely high.
Another problem with this approach is that if the address of the
server changes, the client needs to know the location of the new
server before it can access the object. That is, the objects are not
inherently location transparent.
Why RMI?
If it were possible for a client to invoke the
methods of objects residing on the server with
out actually downloading the object,
considerable performance improvements can be
achieved.
Further it were possible for a client to access a
remote object regardless of on which server the
object actually existed, the objects become
location transparent.
Why RMI?
RMI ( and before RMI , RPC or Remote Procedure Calls) achieves
precisely this objective.
Remote Method Invocation involves using the various classes and
interfaces available in the java.rmi and java.rmi.server packages.
These classes and interfaces provide a framework for an application to
access objects residing on remote hosts by reference(not value).
Once a client obtains a reference to a remote object, it can invoke the
methods on these remote objects as if they existed locally.
Any modification made to the object through the remote object
reference is reflected on the server.
Thus copies are never passed over the network.
Stubs & Skeletons
RMI is ideally suited to applications which require a client
to an application residing on another machine.
Almost all application servers(servers that run applications as
opposed to file servers that serve files or data) can benefit from
RMI or a framework that allows RMI.
RMI is the distributed component model for JAVA applications.
COM/DCOM will be Microsofts equivalent.
This means one Component(java Object) distributed in a
network can be accessed by any other Component on the
network.
This is made possible by what are known as client-stubs
and server-skeletons.
Stubs & Skeletons
The java.rmi.Remote interface
RMI provides an interface called Remote. This is
contained in the java.rmi package.
If a class wants its objects to be accessible remotely, that class
must implement this interface.
Thus we call an object a Remote Object if it is accessible
remotely.
The Remote interface is an empty interface having no methods.
It is a tag interface that tells the Java run time that objects of this
class are remotely accessible.
To make this class have its methods remotely accessible, the
methods need to be declared in an interface that extends the
Remote interface.
Using the
java.rmi.Remote
interface
Using the RMI interface
The exact steps needed to do this are:
1. Declare an interface that extends
java.rmi.Remote
2. Declare methods that need to be accessed
remotely in this
All Remote methods must throw
java.rmi.RemoteException
3. Define a class that implements this
interface.
1. Extend RMI

Declare an interface that extends


java.rmi.Remote:

public interface MyInterface


extends java.rmi.Remote
2. Declare methods that need to
be accessed remotely
public interface:

MyInterface extends java.rmi.Remote


{
//Declare all methods here
public String getMessage()throws
java.rmi.RemoteException;
//More methods
}
3. Define a class that implements
this interface.
Public class MyClass implements MyInterface
{
//Variable definitions/Declarations
//Constructors
//Other methods
public String getMessage()throws
RemoteException
{
return new String(Hello there!);
}
}
RMI Class Hierarchy
A Sample Case

Mortgage Computation via


RMI
A Scenario
Betty just got a job in a mortgage company.
Her supervisor Joy asked her to make the mortgage calculator
available to the public.
That is to say the mortgage calculator will be put on an intranet
or the internet.
The mortgage calculator is an existing software and installed on
an individual computer.
If it is installed on the server, it will be easier to maintain and
update.
This is Betty's first assignment. She felt so excited. She decided
to use Java Remote Method Invocation (RMI) technology.
The calculatePayment() Method
She was ready to start now. She started to look at the Mortgage
calculator class. The key method in the Mortgage class is the
calculatePayment() method listed below:

public double calculatePayment(double principal,


double annualRate, int years){
double monthlyInterest = annualRate / 12;
double monthlyPayment = (principal *
monthlyInterest)
/ (1 - Math.pow(1/ (1 +
monthlyInterest), years * 12));
return monthlyPayment;
}
The calculatePayment() Method
To calculate the monthly payment for a
mortgage, you need three data:
principal,annual rate and term.
When a user provided these three data to an
application, the monthly payment would be returned.
In order to try new RMI features, she quickly
wrote a Mortgage program.
She was going to use this command-line
program to try the RMI features.
Designing a Remote Interface
Since the calculatePayment() method is a key method in
Mortgage class, Betty decided to make this method
remotely available (invoked).
If a user provides principal, annual interest rate and loan term
from a command-line, the monthly payment information will be
printed on the client side.
How to make such method available via network?
According to the RMI technology, you should design a remote
interface first and then put the method signature inside the
remote interface.
Betty checked the new RMI specification, such design step since
jdk 1.1 has not been changed.
What is a remote interface?
According to RMI specification, a remote
interface is an interface that extends
java.rmi.Remote interface and declares a set of
methods that may be invoked from a remote
Java Virtual Machine(JVM).
Note that the java.rmi.Remote interface serves
as a mark to tell the system that methods
declared within this interface may be invoked
from a non-local virtual machine.
What is a remote method?
A remote method is a method that is
declared inside a remote interface.
Betty followed the step and designed a
remote interface named Payment.
She declared the method
calculatePayment() signature and made it
throw RemoteException which is required.
What is a remote method?
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Payment extends Remote {


public double calculatePayment(double
principal, double annualRate, int terms)
throws RemoteException;
}
More on remote methods
Recall that only method signatures or abstract methods are allowed
within an interface, so does the remote interface.
The implementation class will take care of the remote methods.
Right now, we can say that Payment is a remote interface and
calculatePayment() is a remote method.
You may be wondering why the method must throw
RemoteException.
Because remote method invocation may fail in many ways, like server
down, resources unavailable, the method itself may throw exception,
etc.
If the failure happens, the client should be able to know it via the
RemoteException.
More on remote methods
Please note that:
The Payment interface must extends java.rmi.Remote interface. It is
required.
The method signature in the remote interface must throw
java.rmi.RemoteException. It is required too.
If you want multiple methods available remotely, just put these
method signatures inside one or more remote interfaces and let
them throw java.rmi.RemoteException.
This is the first step you should do when you use RMI technology.
Ask yourself if you know how to make a method remotely available,
what is the first step?
The next step is to design a remote object.
Design a Remote Object
According to the RMI specification, a
remote object is one whose methods can
be invoked from another Java virtual
machine, potentially on a different
host(JVM).
Design a Remote Object
You have learnt from the previous section how to
design a remote interface. Do you remember
that you have not implemented the remote
method calculatePayment().
The implementation class is a remote object.
So we need to design a class which implements the
remote interface Payment and defines the remote
method -- calculatePayment().
Design a Remote Object
Betty made the implementation class name
PaymentImpl, because it is easily to be
recognized when you deal with multiple classes.
SincePayment is an interface, "Impl" means
implementation, PaymentImpl is an implementation
class of Payment interface.
We will adopt such name convention in the following
sections.
The Remote Object
import java.rmi.RemoteException;

public class PaymentImpl implements Payment {

public double calculatePayment(double principal, double annRate, int


years)
throws RemoteException {
double monthlyInt = annRate / 12;
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;
}
}
More on Remote Objects
Note that:
The remote object class must implement remote
interface. In this context, it is Payment interface.
The remote object class can have any other
methods not defined in the remote interface, but
these methods can only be used locally, not
remotely, like format() method in the example.
More on Remote Objects
When you implement a remote method, if the
method doesn't throw any exception, the method
head can omit the RemoteException.
Inthis context, we have to throw the
RemoteException, because we have not written any
contract to guarantee that the parameters are valid
before this method being called.
Ask yourself: what is a remote object?
Next step, we should create a server which can
be used to hold the remote object.
Design an RMI Server
When you have a remote object, you need
a carrier to hold it for a possible remote
invocation.
That carrier is often called a server.
What is an RMI Server?
A typical RMI server is an application that
creates a number of remote objects,
makes references to those remote objects
and waits for clients to invoke methods on
those remote objects.
What is an RMI Server?
In this context, a server is a class. In this class,
we need a main method that creates an
instance of the remote object, exports the
remote object, and then binds that instance to a
name in a Java RMI registry.
So we list the server jobs as follows:
1. Create an instance of the remote object
2. Export the remote object
3. Bind the instance to a name in RMI registry
How to create an instance of the
remote object
We already create a remote object class --
PaymentImpl.
To instantiate it, just do it like any other
class instantiation.
PaymentImpl robj = new
PaymentImpl();
Here robj is an instance of the remote
object PaymentImpl.
How to export the remote
object?
We will use this method:
java.rmi.server.UnicastRemoteObject
.exportObject(Remote, int);
to export the remote object.
How to export the remote
object?
When you export a remote object, you make that object
available to accept incoming calls from clients.
The exportObject() method takes 2 parameters, one is an
instance of the remote object, the other is TCP port number.
Note that the same port number can accept incoming calls for
more than one remote objects. The default number for RMI is
1099.
If you pass a zero to the method, the default number 1099 is
used. Of course, you can use a different number to listen to
different remote client calls.

Payment stub = (Payment)


UnicastRemoteObject.exportObject(robj, 0);
How to export the remote
object?
Note that the exportObject() method will return a
stub which is a term used to describe a proxy
class.
The stub class is a key to make remote object
available for remote invocation.
We need to cast it to the remote interface for safe.
The second parameter we use "0" that means we are
going to use the default TCP port number, which is
1099.
An alternative way to export
remote object
You can make the server class extend
java.rmi.server.UnicastRemoteObject
class and use a constructor to export the
object and define a port number.
An alternative way to export
remote object
public class Server extends
java.rmi.server.UnicastRemoteObject
implements aRemoteInterface{
public Server(int port) {
super(port);
}
....
Naming.bind(uniqueName, this);
....
}
What is Java RMI registry
The Java RMI registry is a remote object
that maps names to remote objects.
The methods of LocateRegistry are used
to get a registry operating on a particular
host or host and port.
The method bind() or rebind() binds a
unique name to the reference of the
remote object.
What is Java RMI registry
java.rmi.registry.Registry registry =
java.rmi.registry.LocateRegistry.getRegist
ry();
registry.bind("Mortgage", stub);

or use:
registry.rebind("Mortgage", stub);
The Server Class
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server {

public Server() {}

public static void main(String args[]) {

try {
PaymentImpl robj = new PaymentImpl();
Payment stub = (Payment) UnicastRemoteObject.exportObject(robj, 0);

Registry registry = LocateRegistry.getRegistry();


registry.bind("Mortgage", stub);
System.out.println("Mortgage Server is ready to listen...");

} catch (Exception e) {
System.err.println("Server exception thrown: " + e.toString());
e.printStackTrace();
}
}
}
Design an RMI Client
In the previous sections, we designed a
remote interface, a remote object and a
server.
And now we need to design a client to test
the functionality of the server.
What is an RMI Client?
A typical RMI cient is an application that
gets a remote reference to one or more
remote objects in the server, then invokes
methods on these remote objects.
What is an RMI Client?
Remember that we register a remote
object by name "Mortgage" with a TCP
port number 1099(default).
In our client class, we need some code to
look up the object by name "Mortgage" and a
TCP port number.
When we get the stub class from the RMI
server, we can use this stub class to call the
remote method.
What is an RMI Client?
There are two things you should do before
calling the remote method:
1. Locate a host from the registry mechanism.
2. Look up the remote object by its name.
How to locate a host?
Use the following code to locate a host.
Registry reg =
LocateRegistry.getRegistry(hostName);
In our example, we will use localhost as
the default host. If you run the server in a
different computer, you need to give that
computer's name as a host name.
How to look up a remote object?
You look up a remote object by its name. So,
you must first know the name of the remote
object.
Remember that we register the remote object by
name "Mortgage" in the server's registry.
We use code below to look up "Mortgage" object and
get a stub back.
The stub can be used to access the remote method.
Payment stub = (Payment)
reg.lookup("Mortgage");
How to look up a remote object?

Note that the returned remote object reference


should be cast back to the remote interface.
In this context, we cast to Payment interface.
The most beautiful thing is that a method
invocation on a remote object has the same
syntax as a method invocation on a local object
when you get the reference to a remote object.
The Client Class
Note that we use the returned stub from lookup()
method to call the remote method
calculatePayment() and pass three parameters
obtained from the command-line.
We have to use try/catch block to locate RMI
registry, look up stub class and call the remote
method.
Ifthe server has a problem or the remote method has
a failure, the client side should be able to know it
through the catch clause.
Running the files
Now, you can try the client\server system on
your own computer.
You may be wondering how it could be to use one
computer to try a client\server system.
Remember that, you can start different command-line
windows to try it.
Because every command-line window will get one
distinguished Java Virtual Machine(JVM) instance,
and the communication between two JVMs can be
established in one computer.
We will use localhost as a host for the server.
Running the files
Betty checked the RMI specification, found
that a new feature for running an RMI
server is available.
New feature:
You don't need to generate a stub class
before you start the server.
The stub class will be generated on the fly
if you use jdk 1.5.0 version or above.
Running the files
If you use jdk version below 1.5.0, you
cannot run the examples listed here.
You must use rmic utility to generate a
stub class.
If so, use the following command to
generate a stub class:
set classpath=
rmic -v1.2 Server
Running the files
A file with name Server_stub.class is
generated for JVM communication.
Now you can go to the next step to start
rmiregistry and server.
You need to follow the steps below to
run the server:
1. Start rmiregistry utility
2. Start a server
Running the files
Let's start rmiregistry.
First make sure the classpath is empty, then use
command as follows:
C:\*your_directory*\set classpath=
C:\*your_directory*\start rmiregistry
Note that an empty command-line window will
pop-up.
Don't close it, minimize it if you want.
That window is for rmiregistry.exe program.
Running the Server
Then, you can start a server window in the following
command:
C:\myrmi\start java Server
The pop-up window will have the following printout which
indicates the server is started successfully and ready to
accept client connection.
Mortgage server is ready to listen...
Note that the RMI server we designed is not for one
client connection. It can accept many-client connections
simultaneously.
Running the Server
Then, you can start a server window in the
following command:
C:\myrmi\start java Server
The pop-up window will have the following
printout which indicates the server is started
successfully and ready to accept client
connection.
Mortgage server is ready to
listen...
Running the Client
When the server starts, you are ready to start a
client. Please issue the following command:
C:\myrmi\java Client

When the client starts, the


LocateRegistry.getRegistry("localhost") sends
information to the RMI registry which is held by
the localhost(the Server command-line window)
and asks to look for a remote object named
"Mortgage".
Running the Client
Since the server has such remote object, so the
server sends an instance of stub class back, or
we can say the client downloads the stub class
from the localhost server.
When the client gets the reference to the remote
object, it can use such reference to call remote
method calculatePayment() just like to call a
local method.
This is the most beautiful thing we mentioned
earlier for RMI technology.
Running Everything
The following shows all commands and printout when
you start the RMI server and client system.
C:\myrmi>javac -d . Payment.java
PaymentImpl.java Server.java Client.java

C:\myrmi>set classpath=

C:\myrmi>start rmiregistry

C:\myrmi>start java Server


Running Everything
C:\myrmi>java Client
Usage: java Client principal annualInterest years

For example: java Client 80000 .065 15

You will get the output like the following:

The principal is $80000


The annual interest rate is 6.5%
The term is 15 years
Your monthly payment is $696.89
Running Everything
C:\myrmi>java Client 150000 .060 15
The principal is $150000
The annual interest rate is 6.0%
The term is 15 years
Your monthly payment is $1265.79

C:\myrmi>
Recap
Process of designing an RMI
server and client system
1. Design a remote interface.
2. Design a remote object.
3. Design an RMI server.
4. Design an RMI client.

Você também pode gostar