extra references: The JDK 1.2.2
Documentation
latest revision: minor Nov 6 /
2000
Edit by P.Komisar
Remote Method Invocation (RMI)
is the action of invoking a method (of a remote interface)
on a remote object. A remote object is one whose methods can be invoked
from another Java
Virtual Machine, A method invocation
on a remote object has the same syntax as a method
invocation on a local object.
Distributed systems require that computations running in different address
spaces, potentially on
different hosts, be able to communicate. In such systems, (RMI provides)
a local surrogate (stub)
object which manages the invocation on a remote object.
RMI applications are often comprised of two separate programs: a server
and a client. A typical
server application creates a number of remote objects, makes references
to those remote objects
accessible, and waits for clients to invoke methods on those remote
objects. A typical client
applications gets a remote reference to one or more remote objects
in the server and then invokes
methods on them. RMI provides the mechanism by which the server
and the client communicate
and pass information back and forth. Such an applications is sometimes
referred to as a
distributed object application.
Applications can use one of two mechanisms to obtain references to remote objects:
(1) register
its remote objects with RMI's simple naming facility, the
rmiregistry, or
(2) the application can pass and
return remote object references as
part of its normal operation.
The java.rmi.Remote Interface [2.4.1]
In RMI, a remote interface declares a set of methods that may be invoked
from a remote Java
Virtual Machine such as to satisfy the following requirements:
1) A remote interface must
extend,
the interface java.rmi.Remote, (directly
or by extension)
2) A remote method declaration must
include the exception java.rmi.RemoteException(or
a parent)
3) In a remote method declaration, a
remote object (declared as a parameter or return value) must
be declared as the remote interface, not the implementation class of that
interface.
The parent, java.rmi.Remote, is a marker interface that defines no methods.
public interface Remote{ }
The RemoteException Class [2.4.2]
java.rmi.RemoteException is the
exception superclass the RMI runtime may
throw during a
remote invocation
The RemoteObject Class and its Subclasses
[2.4.3]
java.lang.Object
| java.rmi.server.RemoteObject | java.rmi.server.RemoteServer | java.rmi.activation.Activatable -- +--java.rmi.server.UnicastRemoteObject . |
RMI server functions are provided by java.rmi.server.RemoteObject
and
its subclasses,
RemoteServer& UnicastRemoteObject,
and java.rmi.activation.Activatable.
RemoteObject
provides implementations for the java.lang.Object
methods,
hashCode, equals, and toString,
in a way sensible for remote objects. The methods needed to create
and export remote objects,
(make them available to remote clients), are provided by the classes
UnicastRemoteObject
and Activatable.UnicastRemoteObject class defines a simple (unicast) remote
object whose references
are valid only while the server process is alive.
The class Activatable is abstract,
defining
an
activatable remote object that starts executing when it's remote methods
are invoked. Activatable
can shut itself down when necessary.
The general rules for a class that implements a remote interface are as follows: The class
(1) usually extends
java.rmi.server.UnicastRemoteObject inheriting
the remote behavior
of RemoteObject
and
RemoteServer.
(2) can implement any number of
remote interfaces.
(3) can extend another remote implementation
class.
(4) can define methods that do
not appear in the remote interface, for local but not remote use.
Parameter Passing in Remote Method Invocation [2.6]
An argument to, or a return value from, a remote object can be any
serializable Java object.
This includes Java primitive types,
remote
Java objects, (RMI types)and
non-remote
java objects (those implementing
the java.io.Serializable interface). Classes, for parameters
or return values, that are not available locally are downloaded dynamically
by the RMI system.
Passing Non-remote Objects [2.6.1]
A non-remote object, (passed as
a parameter of a remote method invocation or returned as
a result), is passed by copy,
that is, the object is serialized and sent using the java's
object
serialization mechanism.
Passing Remote Objects [2.6.2]
When passing a remote object as a parameter or return value in a remote
method call, the stub
for the remote object is passed.
A remote object passed as a parameter can only implement
remote interfaces.
Class Annotation [2.6.4]
When an object is sent from one VM to another in a remote method call,
the
RMI system
annotates the class descriptor in the call
stream with information (the URL) of the class
so that the class can be loaded at the receiver. It is a requirement
that classes be downloaded on
demand during remote method invocation.
// this is where an HTTP or FTP file service comes in
Parameter Transmission [2.6.5]
Parameters are written to a subclass of the java.io.ObjectOutputStream
to serialize parameters
to the destination of the remote call. The subclass calls the replaceObject
method for each object
written to the stream via the writeObject method (that includes
objects referenced by those objects
that are written). The replaceObject method of RMI's subclass
of ObjectOutputStream returns
the following:
(1) if the object passed to replaceObject
is an instance of java.rmi.Remote,
then it returns the
remote
object stub,
via a call to the method
RemoteObject.toStub.
(2) if the object passed to replaceObject
is not an instance of java.rmi.Remote,
then the object is
simply
returned. RMI's subclass of ObjectOutputStream also implements the
annotateClass
method that annotates the call
stream with the location of the class so that it can be
downloaded at the receiver.
Since parameters are written to a single ObjectOutputStream, references
that refer to the same
object at the caller will refer to the same copy of the object at the
receiver. At the receiver,
parameters are read by a single ObjectInputStream.
Locating Remote Objects [2.7]
A simple bootstrap name server is
provided for storing named references to remote objects.
A remote object reference can be stored using url-based methods of
the class,
java.rmi.Naming.
The Naming class provides Uniform Resource
Locator,
based methods to lookup, bind, rebind,
unbind,
and list, the name-object
pairings maintained on a particular host and port.
Stubs and Skeletons [3.1]
RMI uses a mechanism, (employed in RPC),
for communicating with remote objects: Stubs and
Skeletons. A
stub
for a remote object acts as a client's local representative
or proxy for the
remote object. The caller invokes
a method on the local stub which is reponsible for carrying out
the method call on the remote object. In RMI, a stub for a remote object
implements the same set
of remote interfaces that a remote object implements.
When a stub's method is invoked, the stub: // does the client side socket / stream / write & read
(1) initiates
a connection with the remote VM containing the remote object.
(2) writes
and transmits (marshals) parameters to the remote VM
(3) waits
for the result of the method invocation
(4) reads
(unmarshals) the return (value or exception)
(5) returns
the value to the caller
The stub hides the serialization of parameters and the network-level
communication in order to
present a simple invocation mechanism to the caller. In the remote
VM, each remote object may
have a corresponding skeleton (in an all-JDK1.2.x
environment, skeletons are not required.*)
.
The skeleton is responsible for dispatching the call to the actual
remote object implementation.
A skeleton receiving an incoming method invocation it does:
(1) reads
(unmarshals) the parameters for the remote method
(2) invokes the method on the actual remote object implementation
(3) writes and transmits (marshals) the result (return value or exception)
to the caller
* Note:
New in JDK1.2, an additional stub protocol eliminates the need for skeletons. Instead, generic code is used to carry out the skeleton's duties. Stubs and skeletons are generated by the rmic compiler |
Thread Usage in Remote Method Invocations [3.2]
Since remote method invocation on the same remote object may execute
concurrently, a remote
object implementation needs to make sure its implementation is thread-safe.
// synchronized
Garbage Collection of Remote Objects [3.3]
When a remote object is not referenced by any client, the RMI runtime
refers to it using a weak
reference. The weak reference allows
the Java virtual machine's garbage collector to discard the
object if no other local references to the object exist. As long as
a local reference to a remote object
exists, it cannot be garbage-collected and it can be passed in remote
calls or returned to clients.
Dynamic Class Loading
[3.4]
public abstract class ClassLoader extends Object // Here are the first few lines of the the JDK1.2.2 API 's description of abstract ClassLoader. // RMI has it's own class RMIClassLoader, which extends Object and is specialized to load // from urls over networks. ClassLoader is an abstract class. A class loader is an object that is responsible for loading classes. Given the name of a class, it should attempt to locate or generate data that constitutes a definition for the class. A typical strategy is to transform the name into a file name and then read a "class file" of that name from a file system. public abstract class RMISocketFactory extends Object // The description from the API of RMISocketFactory shows the different strategies it will // take to make a connection despite a firewall The RMISocketFactory is used by the RMI runtime in order to obtain client and server sockets for RMI calls. The default implementation of the socket factory performs a three-tiered approach to creating client sockets. First, a direct socket connection to the remote VM is attempted. If that fails (due to a firewall), the runtime uses HTTP with the explicit port number of the server. If the firewall does not allow this type of communication, then HTTP to a cgi-bin script on the server is used to POST the RMI call. An application may set the source of sockets for RMI. In this case, the application is responsible for offering up sockets that will penetrate a firewall. . |
RMI allows parameters, return values and exceptions passed in RMI calls
to be any object that is
serializable. RMI uses the object
serialization mechanism to transmit data from one virtual machine
to another and also annotates the call stream with the appropriate
location information so that the
class definition files can be loaded at the receiver.
When parameters and return values for a remote method invocation are
unmarshaled to become
'live objects' in the receiving
VM, class definitions are required for all of the types of objects in
the stream.
The unmarshalling process
(1) first attempts to resolve classes by name in its local class loading context (of the current thread).
(2) RMI
also
provides
a
facility for dynamically loading the
class
definitions
for the actual types
of objects passed as parameters
and return values for remote method invocations from
network
locations specified by the transmitting
endpoint. This includes the dynamic downloading of remote
stub classes corresponding
to particular remote object implementation classes (and used to contain
remote references) as
well as any other type that is passed by value in RMI calls.
For dynamic class loading, the RMI runtime uses special subclasses of
ObjectOutputStream
and ObjectInputStream to marshal
and unmarshal, RMI parameters and return values. These
subclasses override the annotateClass method of ObjectOutputStream
and
the resolveClass
method of ObjectInputStream to
communicate information about where to locate class files
containing the definitions for classes corresponding to the class descriptors
in the stream.
For every class descriptor written
to an RMI marshal stream, the annotateClass method adds
to the stream the result of calling java.rmi.server.RMIClassLoader.getClassAnnotation
for
the class object, which may be null or may be a String
object representing the codebase URL
path (a space-separated list of
URLs) from which the remote endpoint should download the
class definition file for the given class.
For every class descriptor read from an RMI marshal stream, the resolveClass
method reads a
single object from the stream.
If the object is a String (and
the java.rmi.server.useCodebaseOnly property value is not true),
then resolveClass returns the result of calling
RMIClassLoader.loadClass
with
the annotated
String object as
the first parameter and the name of the desired class in the class descriptor
as the
second parameter. Otherwise,
resolveClass
returns the result of calling
RMIClassLoader.loadClass with the name
of the desired class as the only parameter.
The Naming Class [4.3]
The java.rmi.Naming class provides
methods for storing and obtaining references to remote
objects in the remote object registry.
The Naming class' methods take, as one of their
arguments, a name that is a URL formatted java.lang.String
of
the form:
// host:port / name
where host is the host (remote or local) where the registry is located,
port is the port number on
which the registry accepts calls, and where name is a simple string
uninterpreted by the registry.
Both host and port are optional. If host is omitted, the host
defaults to the local host. If port
is omitted, then the port defaults to 1099,
the well-known port that RMI's registry, rmiregistry,
uses.
Binding a name for a remote object
is associating or registering a name for a remote
object
that can be used at a later time to look up that remote object. A remote
object can be associated
with a name using the Naming class'
bind
or rebind methods. Once a remote object is registered
(bound) with the RMI registry on
the local host, callers on a remote (or local) host can lookup
the
remote object by name, obtain its reference, and then invoke remote
methods on the object. The
lookup method returns the remote object associated with the
file portion of the name. The
NotBoundException is thrown if
the name has not been bound to an object. The bind method
binds the specified name to the remote object. It throws the AlreadyBoundException
if
the name
is already bound to an object.The rebind method always binds
the name to the object even if the
name is already bound.The old binding is lost.The unbind method
removes the binding between the
name and the remote object. It will throw the NotBoundException
if there was no binding. The
list method returns an array of String objects containing a
snapshot of the URLs bound in the
registry. Only the host and port information of the URL is needed to
contact a registry for the list
of its contents; thus, the "file" part of the URL is ignored.
The UnicastRemoteObject Class [5.3]
The class java.rmi.server.UnicastRemoteObject
provides
support for creating and exporting
remote objects. The class implements a remote server object with the
following characteristics:
(1) References to such objects are valid only for, at
most, the life of the process creating the remote object.
(2) Communication with the remote object uses a TCP transport.
(3) Invocations, parameters, and results use a stream
protocol for communicating between client and server.
Constructing a New Remote Object [5.3.1]
A remote object implementation (one that implements one or more remote
interfaces) must be
created and exported. Exporting a remote object
makes that object available to accept incoming
calls from clients. For a remote object implementation, exported as
a UnicastRemoteObject,
the exporting involves listening on a TCP
port. (Note that more than one remote object can
accept incoming calls on the same port, so listening on a new port
is not always necessary).
(1) A remote object implemention can extend the class
UnicastRemoteObject
to
make use of it's constructors
that export the object, or
(2) it can extend some other class (or none at all) and
export the object via UnicastRemoteObject's static
exportObject method.
Notes on the UnicastRemoteObject
constructors
The no argument constructor creates and exports a remote object on an anonymous (or arbitrary) port, chosen at runtime.The second form of the constructor takes a single argument, port, that specifies the port number on which the remote object accepts incoming calls. The third constructor creates and exports a remote object that accepts incoming calls on the specified port via a ServerSocket created from the RMIServerSocketFactory; clients will make connections to the remote object via Sockets supplied from the RMIClientSocketFactory. . |
Passing a UnicastRemoteObject in an RMI Call [5.3.3]
When an object of type UnicastRemoteObject
is passed as a parameter or return value in an
RMI call, the object is replaced by the remote
object's stub. A remote object implementation
remains in the virtual machine in which it was created and does
not move (even by value) from
that virtual machine. In other words, a remote
object is passed by reference in an RMI
call; remote object implementations cannot
be passed by value.
Serializing a UnicastRemoteObject [5.3.4]
Information contained in UnicastRemoteObject
is
transient
and is not saved if an object of that
type is written to a user-defined ObjectOutputStream.
Remote Object Activation: Overview [7.1]
Distributed object systems are designed
to support long-lived persistent objects.
Given that
these systems will be made up of many thousands (perhaps millions)
of such objects, it would be
unreasonable for object implementations to become active and remain
active, taking up valuable
system resources, for indefinite periods of time. In addition, clients
need the ability to store persistent
references to objects so that communication among objects can be re-established
after a system
crash, since typically a reference to a distributed object is valid
only while the object is active.
Object activation is a mechanism
for providing persistent references to objects and managing the
execution of object implementations. In RMI, activation
allows objects to begin execution on
an as-needed basis. When an activatable
remote object is accessed (via a method invocation)
if that remote object is not currently executing, the system initiates
the object's execution inside an
appropriate Java VM.
Note: In the JDK, RMI provides an implementation of the
activation system interfaces. In order to
use activation, you must first run the activation system daemon rmid. |
RMI Wire Protocol
[10]
10.1 Overview
10.2 RMI Transport Protocol
10.3 RMI's Use of Object Serialization Protocol
10.4 RMI's Use of HTTP POST Protocol
10.5 Application Specific Values for RMI
10.6 RMI's Multiplexing Protocol
A Exceptions In RMI
B Properties In RMI