Remote Method Invocation RMI

Distributed Objects

Most of the materials in these notes were from accesses provided by the various sources on my RMI reference page and the RMI Specs (an amazing page that makes me realize I am biting off more than I can chew by trying to do all of these things in one semester). Also

Distributed systems require that computations running in different address spaces, potentially on different hosts, be able to communicate. For a basic communication mechanism, the Java language supports sockets, which are flexible and sufficient for general communication. However, sockets require the client and server to engage in applications-level protocols to encode and decode messages for exchange, and the design of such protocols is cumbersome and can be error-prone.

An alternative to sockets is Remote Procedure Call (RPC), which abstracts the communication interface to the level of a procedure call. Instead of working directly with sockets, the programmer has the illusion of calling a local procedure, when in fact the arguments of the call are packaged up and shipped off to the remote target of the call. RPC systems encode arguments and return values using an external data representation, such as XDR.

RPC, however, does not translate well into distributed object systems, where communication between program-level objects residing in different address spaces is needed. In order to match the semantics of object invocation, distributed object systems require remote method invocation or RMI. In such systems, a local surrogate (stub) object manages the invocation on a remote object.

The Java remote method invocation system was designed to operate in the Java environment. While other RMI systems can be adapted to handle Java objects, these systems do not have the "seamless" integration with the Java system due to their interoperability requirement with other languages.

System Goals

The goals for supporting distributed objects in the Java language are:

Underlying all these goals is a general requirement that the RMI model be both simple (easy to use) and natural (fits well in the language).

In addition, the RMI system should allow extensions such as garbage collection of remote objects, server replication, and the activation of persistent objects to service an invocation. These extensions should be transparent to the client and add minimal implementation requirements on the part of the servers that use them. To support these extensions, the system should also support:

Remote Method Invocation (RMI): Technology for Distributed Java

RMI is a distributed technology that extends the pure Java object model to the network. RMI enables objects in one Java Virtual Machine to seamlessly invoke methods on objects in a remote Virtual Machine.

RMI lets you distribute Java objects across the Internet and intranets, enabling you to design and deploy extensible systems that can be modified by dynamically adding new behavior. RMI is the next step in RPC (Remote Procedure Call) systems, which have progressed from procedural to object-based to object-oriented with RMI.

RMI helps programmers create distributed Java to Java applications in which methods of remote Java objects can be invoked from other Java Virtual Machines. RMI supports traditional distribution models - such as client/server and peer-to-peer - and enriches these models with new kinds of agent-based distributed applications.

A Java program can make a call on a remote object once it obtains a reference to the object, either by looking it up in the simple name facility provided by RMI, or by receiving the reference as an argument or a return value. A client can call a remote object in a server, and that server can also be a client of other remote objects. RMI uses Object Serialization to pass parameters and does not truncate types, supporting true object- oriented polymorphism.

RMI's use of Object Serialization to pass parameters to and return values from remote methods allows a program to pass many built-in Java objects, such as vectors, hashtables and dates. RMI allows a program to exchange and return arbitrary user-defined objects. Passing objects by value is powerful because object behavior - and not just the data - can be sent to another Java Virtual Machine.

Two Dukes doing RMI

The Java Distributed Object Model

In the Java distributed object model, a remote object is one whose methods can be invoked from another Java Virtual Machine, potentially on a different host. An object of this type is described by one or more remote interfaces, which are Java interfaces that declare the methods of the remote object. A remote object implements one or more remote interfaces...

Remote method invocation (RMI) is the action of invoking a method of a remote interface on a remote object. Most importantly, a method invocation on a remote object has the same syntax as a method invocation on a local object.

The Distributed and Nondistributed Models Contrasted

The Java distributed object model preserves the Java object model in the following ways:

The Java distributed object model extends the Java object model in several ways:

The primary advantages of RMIObviously shamelessly taken from a SUN page

Remote Method Invocation Architecture Overview

The RMI system consists of three layers:
The Remote Method Invocation Three-Layer Architecture

Because the boundary at each layer is defined by a specific interface and protocol, each layer is independent of the next, and can be replaced by an alternate implementation without affecting the other layers in the system.

Transparent transmission of objects from one address space to another is achieved through Object Serialization, a technique that supports the encoding of objects - and the objects they can reach - into a stream of bytes. Object Serialization also supports the complementary reconstruction of the object graph from the stream.

Another technique - known as dynamic stub loading - is used to support client-side stubs that implement the same set of remote interfaces as a remote object. When a stub of the exact type is not already available to the client, dynamic stub loading allows the client to use the Java Platform's built-in operators for casting and type-checking.

Diagram of RMI Architecture

Java RMI Architecture

RMI is a layer on top of the Java Virtual Machine which leverages the Java system's built-in garbage collection, security and class-loading mechanisms. The application layer sits on top of the RMI system. A Remote Method Invocation from a client to a remote server object travels down through the layers of the RMI system to the client-side transport. Next, the invocation is sent - potentially via network communication - to the server-side transport, where it then travels up through the transport to the server.

A client invoking a method on a remote server object actually uses a stub or proxy as a conduit to the remote object. A client-held reference to a remote object is a reference to a local stub, which is an implementation of the remote interfaces of the object and which forwards invocation requests to it via the remote reference layer. Stubs are generated using the rmic compiler

The remote reference layer in the RMI system separates out the specific remote reference behavior from the client stub. Any call initiated by the stub is done directly through the reference layer, enabling appropriate reference semantics to be carried out. For example, if a remote reference had the behavior of connection retry, it would attempt to establish the retry connection on behalf of the stub. When the connection initiation succeeded, the reference layer would forward the marshaling of arguments and send the RMI call to the underlying transport for that reference type.

Another kind of remote reference could be one that carries out multicast to a set of replicas for a remote object (multiplexing ... multicasting?). The stub for the remote object would call through the remote reference layer, which in turn would communicate to the replica set via the transport. The reference layer provides the abstraction necessary for multiple reference semantics to be carried out without changing a stub's form. A stub simply instructs the layer beneath it to initiate a call, marshals and unmarshals parameters, and returns the result. Also handled by the remote reference layer are the reference semantics for the server. The remote reference layer, for example, abstracts the different ways of referring to objects that are implemented in (a) servers that are always running on some machine, and (b) servers that are run only when some method invocation is made on them (activation). At the layers above the remote reference layer, these differences are not seen.

The transport layer is responsible for connection setup, connection management, and keeping track of and dispatching to remote objects (the targets of remote calls) residing in the transport's address space.

In order to dispatch to a remote object, the transport forwards the remote call up to the remote reference layer. The remote reference layer handles any server-side behavior that needs to occur before handing off the request to the server-side skeleton. The skeleton for a remote object makes an up call to the remote object implementation which carries out the actual method call.

The return value of a call is sent back through the skeleton, remote reference layer, and transport on the server side, and then up through the transport, remote reference layer, and stub on the client side.

The Stub/Skeleton Layer

The stub/skeleton layer is the interface between the application layer and the rest of the RMI system. This layer does not deal with specifics of any transport, but transmits data to the remote reference layer via the abstraction of marshal streams. Marshal streams employ a mechanism called object serialization which enables Java objects to be transmitted between address spaces. Objects transmitted using the object serialization system are passed by copy to the remote address space, unless they are remote objects, in which case they are passed by reference.

A stub for a remote object is the client-side proxy for the remote object. Such a stub implements all the interfaces that are supported by the remote object implementation. A client-side stub is responsible for:

A skeleton for a remote object is a server-side entity that contains a method which dispatches calls to the actual remote object implementation. The skeleton is responsible for:

The appropriate stub and skeleton classes are determined at run time and are dynamically loaded as needed, as described in the next notes. Stubs and skeletons are generated using the rmic compiler J2SE 5.0 .

The Remote Reference Layer

The remote reference layer deals with the lower-level transport interface. This layer is also responsible for carrying out a specific remote reference protocol which is independent of the client stubs and server skeletons.

Each remote object implementation chooses its own remote reference subclass that operates on its behalf. Various invocation protocols can be carried out at this layer. Examples are:

The remote reference layer has two cooperating components: the client-side and the server-side components. The client-side component contains information specific to the remote server (or servers, if the remote reference is to a replicated object) and communicates via the transport to the server-side component. During each method invocation, the client and server-side components perform the specific remote reference semantics. For example, if a remote object is part of a replicated object, the client-side component can forward the invocation to each replica rather than just a single remote object.

In a corresponding manner, the server-side component implements the specific remote reference semantics prior to delivering a remote method invocation to the skeleton. This component, for example, would handle ensuring atomic multicast delivery by communicating with other servers in a replica group (note that multicast delivery is not part of the JDK 1.1 release of RMI).

The remote reference layer transmits data to the transport layer via the abstraction of a stream-oriented connection. The transport takes care of the implementation details of connections. Although connections present a streams-based interface, a connectionless transport can be implemented beneath the abstraction.

The Transport Layer

In general, the transport layer of the RMI system is responsible for:

The concrete representation of a remote object reference consists of an endpoint and an object identifier. This representation is called a live reference. Given a live reference for a remote object, a transport can use the endpoint to set up a connection to the address space in which the remote object resides. On the server side, the transport uses the object identifier to look up the target of the remote call.

The transport for the RMI system consists of four basic abstractions:

A transport defines what the concrete representation of an endpoint is, so multiple transport implementations may exist. The design and implementation also supports multiple transports per address space, so both TCP and UDP can be supported in the same virtual machine. Note that the RMI transport interfaces are only available to the virtual machine implementation and are not available directly to the application.

Thread Usage in Remote Method Invocations

A method dispatched by the RMI runtime to a remote object implementation (a server) may or may not execute in a separate thread. Some calls originating from the same client virtual machine will execute in the same thread; some will execute in different threads. Calls originating from different client virtual machines will execute in different threads. Other than this last case of different client virtual machines, the RMI runtime makes no guarantees with respect to mapping remote object invocations to threads.

Simple Examples Getting feet wet

You should all have these available if you downloaded docs with the JDK. The local Getting Started Using RMI page walks us through setting the HelloWorld RMI applet up.
  1. From the JDK: JAVA_HOME/docs/guide/rmi/examples/hello
  2. From the JDK: JAVA_HOME/docs/guide/rmi/examples/stock
However since we cannot run the Applet using RMI for security reasons, I suggest the application version below (besides, things have changed since the first version):

RMI index and the SUN location for the Getting Started tutorial for JDK 5.0 ( local ) as well as tutorial trail continued

the RMI Specs page has another example of setting everything up.