1.
Networking has been concerned with two fundamental
applications.
·
The first application is moving files and data
between hosts, which is handled by FTP, SMTP (email), HTTP, NFS, and many other
protocols.
·
The second application is allowing one host to
run programs on another host.
2.
Remote Method Invocation (RMI) is an example of the
second application for networking: running a program on a remote host from a
local machine.
3.
RMI is a core Java API and class library that allows
Java programs to call certain methods on a remote server.
4.
The methods running on the server can invoke methods in
objects on the client.
5.
Return values and arguments can be passed back and
forth in both directions.
6.
In essence, parts of a single program run in a Java
virtual machine on a local client while other parts of the same program run on
a Java virtual machine on a remote server.
7.
RMI creates the illusion that the distributed program
is running on one system with one memory space holding all the code and data
used on either side of the actual physical connection.
RMI API
1.
The Remote Method Invocation API lets Java objects on
different hosts communicate with each other.
2.
A remote object lives on a server.
3.
Each remote object implements a remote interface that
specifies which of its methods can be invoked by clients.
4.
Clients invoke the methods of the remote object almost
exactly as they invoke local methods.
Example an object running on a local
client can pass a database query as a String argument to a method in a database
object running on a remote server to ask it to sum up a series of records. The
server can return the result to the client as a double.
This
is more efficient than downloading all the records and summing them up locally.
Programmer's perspective
From
the programmer's perspective, remote objects and methods work just like the local
objects and methods you're accustomed to. All the implementation details are hidden.
- Import one package.
- Look up the remote object
in a registry (which takes one line of code).
- Make sure that you catch
RemoteException when you call the object's methods.
- From that point on, you
can use the remote object almost as freely and easily as you use an object
running on your own system.
Remote
Object
- is an object whose methods
may be invoked from a different Java virtual machine than the one in which
the object itself lives, generally one running on a different computer.
- Each remote object
implements one or more remote interfaces that declare which methods
of the remote object can be invoked by the foreign system.
Object
Serialization
a way
to convert the object into a stream of bytes.
When
an object is passed to or returned from a Java method, what's really
transferred is a reference to the object. Passing objects between two machines
thus raises some problems.
- The remote machine can't
read what's in the memory of the local machine.
- A reference that's valid
on one machine isn't meaningful on the other.
There
are two ways around this problem.
- A special remote reference
to the object (a reference that points to the memory in the remote
machine) can be passed,
- or a copy of the object
can be passed.
When
the local machine passes a remote object to the remote machine, it passes a
remote reference. The object has never really left the remote machine.
However,
when the local machine passes one of its own objects to the remote machine, it
makes a copy of the object and sends the copy. The copy moves from the local
machine to the remote machine.
The
RMI Layer Model
1.
To the programmer, the client appears to talk directly
to the server.
2.
In reality, the client program talks only to a stub.
The stub passes that conversation along to the remote reference layer, which
talks to the transport layer.
3.
The transport layer on the client passes the data
across the Internet to the transport layer on the server.
4.
The server's transport layer then communicates with the
server's remote reference layer, which talks to a piece of server software
called the skeleton.
5.
The skeleton communicates with the server itself.
6.
In the other direction (server-to-client), this flow is
simply reversed.
7.
Logically, data flows horizontally (client-to-server
and back), but the actual flow of data is vertical.
Registry
The
registry is a program that runs on the server. It contains a list of all the
remote objects that server is prepared to export and their names. A client
connects to the registry and gives it the name of the remote object that it
wants. Then the registry sends the client a reference to the object that it can
use to invoke methods on the server.
Stub
The
stub is a local object that implements the remote interfaces of the remote
object; this means that the stub has methods matching the signatures of all the
methods the remote object exports. In effect, the client thinks it is calling a
method in the remote object, but it is really calling an equivalent method in
the stub. Stubs are used in the client's virtual machine in place of the real
objects and methods that live on the server. When the client invokes a method,
the stub passes the invocation to the remote reference layer.
Skelton
The
skeleton reads the arguments and passes the data to the server program, which
makes the actual method call. If the method call returns a value, that value is
sent down through the skeleton, remote reference, and transport layers on the
server side, across the Internet and then up through the transport, remote
reference, and stub layers on the client side.
Remote Reference
Layer
On
client side, the remote reference layer translates the local reference to the
stub into a remote reference to the object on the server. Then it passes the
invocation to the transport layer. On server side, the remote reference layer
converts the remote references sent by the client into references for the local
virtual machine. Then it passes the request to the skeleton.
Transport Layer
The
transport layer sends the invocation across the Internet.
The
Server Side
1.
To create a new remote object, first define an
interface that extends the
java.rmi.Remote interface.
2.
Subinterface of Remote determines which methods of the
remote object may be
called by clients. A remote object may have many public
methods, but only those
declared in a remote interface can be invoked remotely.
The other public methods
may be invoked only from within the virtual machine where
the object lives.
3.
Each method in your subinterface must declare that it
throws RemoteException.
RemoteException is the superclass for most of the
exceptions that can be thrown
when RMI is used. Many of these are related to the
behavior of external systems and
networks and are thus beyond your control.
import java.rmi.*;
import java.math.BigInteger;
public interface Fibonacci extends Remote {
public BigInteger getFibonacci(int n) throws RemoteException;
public BigInteger getFibonacci(BigInteger n) throws
RemoteException;
}
4.
The next step is to define a class that implements this
remote interface. This class
should extend java.rmi.server.UnicastRemoteObject, either
directly or ndirectly
(i.e., by extending another class that extends
UnicastRemoteObject):
public class UnicastRemoteObject extends RemoteServer
public class UnicastRemoteObject extends RemoteServer
5.
If extending UnicastRemoteObject isn't convenient—for
instance, because you'd
like to extend some other class—then you can instead
export your object as a remote
object by passing it to one of the static
UnicastRemoteObject.exportObject( )
methods:
public static RemoteStub exportObject(Remote obj)throws
RemoteException
Example
import
java.rmi.*;
import
java.net.*;
import
java.rmi.server.UnicastRemoteObject;
public
class FibonacciImpl implements Fibonacci {
public
FibonacciImpl( ) throws RemoteException {
UnicastRemoteObject.exportObject(this);
}
public
BigInteger getFibonacci(int n) throws RemoteException {
//impleementation
}
public
BigInteger getFibonacci(BigInteger n) throws RemoteException
{
//impleementation
}
}//End
Class
Public
class FibonacciServer
{
public
static void main(String[] args) {
try {
FibonacciImpl f = new FibonacciImpl( );
Naming.rebind("fibonacci", f);
System.out.println("Fibonacci Server ready.");
}
catch
(RemoteException re) {
System.out.println("Exception in FibonacciImpl.main:
" + re);
}
catch
(MalformedURLException e) {
System.out.println("MalformedURLException " +
e);
}
}
Although
the main( ) method finishes fairly quickly here, the server will continue to
run
because a nondaemon thread is spawned when the FibonacciImpl( ) exports the
FibonacciImpl
object.
Client Side
import
java.rmi.*;
import
java.net.*;
public
class FibonacciClient {
public
static void main(String args[]) {
try {
Object o = Naming.lookup(“rmi://localhost:12/Fibonacci”);
Fibonacci calculator = (Fibonacci) o;
try {
BigInteger f = calculator.getFibonacci(1000);
}
}
}catch
(RemoteException e) {
System.err.println("Remote object threw exception
" + e);
}
catch
(NotBoundException e) {
System.err.println(
"Could not find the requested remote object on the
server");
}
}
}
Compiling
the Stubs
rmic
FibonacciImpl
copy
the Fibonacci.class and FibonacciImpl_Stub.class files to both
the directory on the remote server from which the Fibonacci
object will be run and the directory on the local client where the Fibonacci object will be invoked.
Starting
the Server
1.
Start the registry first.
C:> start rmiregistry
The registry runs in the background. The registry tries to
listen to port 1,099 by default.
2.
Run the Server
Running
the Client
1.
Make sure that the client system has FibonacciClient.class,
Fibonacci.class, and FibonacciImpl_Stub.class in its class path.
2.
Run the Client
CallBacks
Server
can call back methods of clients
Threads
The RMI specification says "A method dispatched by the
RMI runtime to a remote object implementation may or may not execute in a
separate thread. The RMI runtime makes no guarantees with respect to mapping
remote object invocations to threads. Since remote method invocation on the
same remote object may execute concurrently, a remote object implementation
needs to make sure its implementation is threadsafe."
In other words, the RMI implementation is free to dispatch
an incoming RMI call on any thread. It may dispatch them all consecutively to
the same thread; concurrently to many threads; or any other way it likes. There
is no implication that there is—or is not—one specific dispatch thread per
exported object. There is no guarantee about mapping clients, or client
threads, to server threads. There are no guarantees and you can make no
assumptions. Your implementations of remote methods must be threadsafe. It is
up to you.
No comments:
Post a Comment