jump to navigation

Remote Method Invocation (RMI) August 8, 2005

Posted by Coolguy in J2SE.
trackback
  • The Java Remote Method Invocation (RMI) system allows an object running in one Java Virtual Machine (VM) to invoke methods on an object running in another Java VM.
  • RMI provides for remote communication between programs written in the Java programming language.

Comparison of Distributed and Nondistributed Java Programs

Local Object Remote Object
Object Definition A local object is defined by a Java class. A remote object’s exported behavior is defined by an interface that must extend the Remote interface.
Object Implementation A local object is implemented by its Java class. A remote object’s behavior is executed by a Java class that implements the remote interface.
Object Creation A new instance of a local object is created by the new operator. A new instance of a remote object is created on the host computer with the new operator. A client cannot directly create a new remote object (unless using Java 2 Remote Object Activation).
Object Access A local object is accessed directly via an object reference variable. A remote object is accessed via an object reference variable which points to a proxy stub implementation of the remote interface.
References In a single JVM, an object reference points directly at an object in the heap. A “remote reference” is a pointer to a proxy object (a “stub”) in the local heap. That stub contains information that allows it to connect to a remote object, which contains the implementation of the methods.
Active References In a single JVM, an object is considered “alive” if there is at least one reference to it. In a distributed environment, remote JVMs may crash, and network connections may be lost. A remote object is considered to have an active remote reference to it if it has been accessed within a certain time period (the lease period). If all remote references have been explicitly dropped, or if all remote references have expired leases, then a remote object is available for distributed garbage collection.
Finalization If an object implements the finalize() method, it is called before an object is reclaimed by the garbage collector. If a remote object implements the Unreferenced interface, the unreferenced method of that interface is called when all remote references have been dropped.
Garbage Collection When all local references to an object have been dropped, an object becomes a candidate for garbage collection. The distributed garbage collector works with the local garbage collector. If there are no remote references and all local references to a remote object have been dropped, then it becomes a candidate for garbage collection through the normal means.
Exceptions Exceptions are either Runtime exceptions or Exceptions. The Java compiler forces a program to handle all Exceptions. RMI forces programs to deal with any possible RemoteException objects that may be thrown. This was done to ensure the robustness of distributed applications.

Java RMI Architecture

  • RMI allows the code that defines the behavior and the code that implements the behavior to remain separate and to run on separate JVMs.
  • This fits nicely with the needs of a distributed system where clients are concerned about the definition of a service and servers are focused on providing the service.
  • Key to understanding RMI is to remember that interfaces define behavior and classes define implementation.

  • A client program makes method calls on the proxy object.
  • RMI sends the request to the remote JVM, and forwards it to the implementation
  • Any return values provided by the implementation are sent back to the proxy and then to the client’s program.
  • A typical server application creates some remote objects, makes references to them accessible, and waits for clients to invoke methods on these remote objects.
  • A typical client application 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 application is sometimes referred to as a distributed object application
  • Distributed object applications need to
  • Locate remote objects: Applications can use one of two mechanisms to obtain references to remote objects. An application can register its remote objects with RMI’s simple naming facility, the rmiregistry, or the application can pass and return remote object references as part of its normal operation
  • Communicate with remote objects: Details of communication between remote objects are handled by RMI; to the programmer, remote communication looks like a standard Java method invocation.
  • Load class bytecodes for objects that are passed around: Because RMI allows a caller to pass objects to remote objects, RMI provides the necessary mechanisms for loading an object’s code, as well as for transmitting its data.

RMI Architecture Layers

The RMI implementation is essentially built from three abstraction layers.

  • The first is the Stub and Skeleton layer, which lies just beneath the view of the developer.This layer intercepts method calls made by the client to the interface reference variable and redirects these calls to a remote RMI service.
  • The next layer is the Remote Reference Layer. This layer understands how to interpret and manage references made from clients to the remote service objects.In the Java 2 SDK, this layer was enhanced to support the activation of dormant remote service objects via Remote Object Activation.
  • The transport layer is based on TCP/IP connections between machines in a network. It provides basic connectivity, as well as some firewall penetration strategies

Stub and Skeleton Layer

  • The stub and skeleton layer is responsible for marshaling and unmarshaling the data and transmitting and receiving them to/from the Remote Reference Layer.
  • The stub and skeleton layer of RMI lie just beneath the view of the Java developer.
  • Marshalling is the process of gathering data and transforming it into a standard format before it is transmitted over a network so that the data can transcend network boundaries.

Stub functions:

  • Initiating a call to the remote object (via remote reference layer).
  • Marshaling arguments (using serialization)
  • Informing the remote reference layer that the call should be invoked
  • Unmarshaling the return value or exception from a marshal stream
  • Informing the remote reference layer that the call is complete.

Skeleton functions

  • Unmarshaling arguments from the marshal stream
  • Making the up-call to the actual remote object implementation
  • Marshaling the return value of the call or an exception (if one occurred) onto the marshal stream
  • A skeleton is a helper class that is generated for RMI to use. The skeleton understands how to communicate with the stub across the RMI link. The skeleton carries on a conversation with the stub; it reads the parameters for the method call from the link, makes the call to the remote service implementation object, accepts the return value, and then writes the return value back to the stub.

Remote Reference Layer

  • The Remote Reference Layers defines and supports the invocation semantics of the RMI connection.
  • RMI supports activatable remote objects

Transport Layer

  • The Transport Layer makes the connection between JVMs.Even if two JVMs are running on the same physical computer, they connect through their host computer’s TCP/IP network protocol stack.
  • All connections are stream-based network connections that use TCP/IP.
  • Functions are:
  • Setting up and managing connections
  • Monitoring connection “liveness.”
  • Listening for incoming calls
  • Maintaining a table of remote objects that reside in the address space.
  • Setting up a connection for an incoming call
  • Locating the dispatcher for the target of the remote call and passing the connection to this dispatcher
  • On top of TCP/IP, RMI uses a wire level protocol called Java Remote Method Protocol (JRMP) and RMI-IIOP.

Naming Remote Objects

  • RMI can use many different directory services, including the Java Naming and Directory Interface (JNDI).
  • RMI itself includes a simple service called the RMI Registry, rmiregistry. The RMI Registry runs on each machine that hosts remote service objects and accepts queries for services, by default on port 1099.

Server side

  • On a host machine, a server program creates a remote service by first creating a local object that implements that service.
  • Next, it exports that object to RMI.
  • When the object is exported, RMI creates a listening service that waits for clients to connect and request the service.
  • After exporting, the server registers the object in the RMI Registry under a public name.

Client side

  • RMI Registry is accessed through the static class Naming
  • It provides the method lookup() that a client uses to query a registry.
  • The method lookup() accepts a URL that specifies the server host name and the name of the desired service.
  • The method returns a remote reference to the service object.
  • The URL takes the form:
    ‘rmi://host_name [:name_service_port]/service_name’

Using RMI

  • A working RMI system is composed of several parts.
    Interface definitions for the remote services
    Implementations of the remote services
    Stub and Skeleton files
    A server to host the remote services
    An RMI Naming service that allows clients to find the remote services
    A class file provider (an HTTP or FTP server)
    A client program that needs the remote services

Interfaces

public interface Calculator extends java.rmi.Remote

{

public long add(long a, long b) throws java.rmi.RemoteException;

public long sub(long a, long b) throws java.rmi.RemoteException;

public long mul(long a, long b) throws java.rmi.RemoteException;

public long div(long a, long b) throws java.rmi.RemoteException;

}

Implementation

public class CalculatorImpl extends java.rmi.server.UnicastRemoteObject implements Calculator

{

public CalculatorImpl() throws java.rmi.RemoteException

{ super();

}

public long add(long a, long b) throws java.rmi.RemoteException

{ return a + b; }

public long sub(long a, long b) throws java.rmi.RemoteException

{ return a – b; }

public long mul(long a, long b) throws java.rmi.RemoteException

{ return a * b; }

public long div(long a, long b) throws java.rmi.RemoteException

{ return a / b; }

}

Stubs and Skeletons

rmic CalculatorImpl

Host Server

import java.rmi.Naming;public class CalculatorServer

{ public CalculatorServer()

{ try

{

Calculator c = new CalculatorImpl();

Naming.rebind(“rmi://localhost:1099/CalculatorService”, c);

}

catch (Exception e)

{

System.out.println(“Trouble: ” + e);

}

}

public static void main(String args[])

{

new CalculatorServer();

}

}

Client

import java.rmi.Naming;

import java.rmi.RemoteException;

import java.net.MalformedURLException;

import java.rmi.NotBoundException;

public class CalculatorClient

{

public static void main(String[] args)

{

try

{

Calculator c = (Calculator) Naming.lookup( “rmi://localhost /CalculatorService”);

System.out.println( c.sub(4, 3) );

}

catch (MalformedURLException murle)

{

System.out.println();

System.out.println( “MalformedURLException”); System.out.println(murle);

}

catch (RemoteException re)

{

System.out.println();

System.out.println( “RemoteException”); System.out.println(re);

}

catch (NotBoundException nbe)

{

System.out.println();

System.out.println( “NotBoundException”); System.out.println(nbe);

}

catch ( java.lang.ArithmeticException ae)

{

System.out.println();

System.out.println( “java.lang.ArithmeticException”); System.out.println(ae); }

}

}

Running the RMI System

rmiregistry

java CalculatorServer

java CalculatorClient

Parameters in RMI

  • The normal semantics for Java technology is pass-by-value. When a parameter is passed to a method, the JVM makes a copy of the value, places the copy on the stack and then executes the method. When the code inside a method uses a parameter, it accesses its stack and uses the copy of the parameter. Values returned from methods are also copies. When a primitive data type (boolean, byte, short, int, long, char, float, or double) is passed as a parameter to a method, the mechanics of pass-by-value are straightforward
  • The mechanics of passing an object as a parameter are more complex. Recall that an object resides in heap memory and is accessed through one or more reference variables
  • When a primitive data type is passed as a parameter to a remote method, the RMI system passes it by value.Values are passed between JVMs in a standard, machine-independent format. This allows JVMs running on different platforms to communicate with each other reliably.
  • When an object is passed to a remote method, the semantics change from the case of the single JVM. RMI sends the object itself, not its reference, between JVMs. It is the object that is passed by value, not the reference to the object. Similarly, when a remote method returns an object, a copy of the whole object is returned to the calling program
  • RMI uses a technology called Object Serialization to transform an object into a linear format that can then be sent over the network wire. Object serialization essentially flattens an object and any objects it references. Serialized objects can be de-serialized in the memory of the remote JVM and made ready for use by a Java program

More:

http://www.cs.rice.edu/~druschel/comp413/lectures/rmi-corba.html

http://java.sun.com/developer/onlineTraining/rmi/RMI.html

Advertisements

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: