Remote Objects in Java

References

Introduction

Remote Method Invocation provides a means for objects in different virtual machines to interact with each other. These objects may reside on virtual machines geographically located worlds apart.

One important feature of RMI is that it presents a programmatic interface for networking rather than relying on sockets and streams techniques. The higher level interface that RMI offers, treats remote objects as if they were local.

Stubs and Skeletons

When client code wants to invoke a remote method on a remote object, it actually calls a regular Java method that is encapsulated in a surragate object called a stub. The stub resides on the client machine, not on the server. The stub packages a block of bytes, the parameters used in the remote method. This packaging uses device independent encoding for each parameter. For example, numbers are always sent in big-endian format. Strings and objects references are sent across using the Java object serialization mechanism. This process of encoding the parameters into a format suitable for transporting them between objects running in different Java Virtual Machines is called parameter marshalling.

In summary the stub method on the client builds an information block that consists of:

The stub then sends this information to the server. On the server side, a skeleton object makes sense out of the information contained in the packet and passes that information to the actual object executing the remote method. Specifically, the skeleton performs five actions for every remote method call:

The stub unmarshals the return value or exception from the server. This value becomes the return value of the remote method call. Or, if the remote method threw an exception, the stub re-throws it in the process space of the caller.

Skeletons

On the server side, the skeleton object takes care of all the details of "remoteness" so that the actual remote object doesn't need to worry about them. The remote object can be coded as if it was a local object - the skeleton insulates the remote object form the RMI. Below is the list of the skeleton's tasks:

Policy Files

Code is granted permissions in what is called a policy file. If you look in the %JAVA_HOME%/jre/lib/security security directory, you will find the policy file for your JVM named java.policy. This file can be edited manually or by using the policytool program found in the %JAVA_HOME%/bin directory. See policy file example below:

/* AUTOMATICALLY GENERATED ON Wed Oct 09 12:08:26 EDT 2002*/
/* DO NOT EDIT */

grant codeBase "file://g:/Users/Juang/-" {
permission java.security.AllPermission;
permission java.net.SocketPermission "*", "accept, connect, listen, resolve";
};

 

The OSI Reference Model defines a framework that consists of seven layers of network communication. The figure below shows how RMI can be described by this model.

The Remote Reference Layer is responsible for carrying out the semantics of the invocation, it transmits data to the Transport Layer using connection-oriented streams - i.e. TCP (rather than UDP). The Transport Layer in the current RMI
implementation is TCP-based, but a UDP-based tarnsport layer could be substituted. Finally, the Transport Layer is responsible for setting up connections, and managing those connections.

Developing Client-Server applications using JavaRMI


Writing Client-Server applications using JavaRMI involves 7 simple steps:

  1. Define a remote interface, place a copy of the interface extending Remote on the server and client
  2. Place the implementation class extending RemoteObject on the server
  3. Writing an application (or an applet) that uses the remote objects
  4. Generating stubs (client proxies) and skeletons (server entities) running rmic on the implementation class
  5. Starting the registry service on the server (rmiregistry)
  6. Start the program that creates and registers objects of the implementation class on the server
  7. Run the client to connect to the remote service


Let's look at each step by developing a simple application as an example to help us in understanding each step.
The sample application is an lookup information server. The information server will perform name lookups on names in a phone database (file).

The first step is to define a remote interface for the remote objects. Why do we need an interface? The programmer of a client should be able to tell what operations the lookup information server (LookupServer.java) provides and how to use these operations just by looking at the interface we define.

The source and data files required for the lookup information example is available here. An additional example is available from this link ---> New RMI Source