RMI In Detail
Peter Komisar  ©   Conestoga College      latest version 5.5 / 2008
added references:  jGuru: Remote Method Invocation(RMI) , Govind Seshardri 
http://developer.java.sun.com/developer/onlineTraining/rmi/index.html
The RMI Specification, @ the Sun site


The RMI Interface & RemoteObject Classes

Quick Review

Remote Method Invocation lets a method to be 'called'
on a
remote object. RMI is a  Java API so the remote
object will be invoked on an object that is being hosted
on another Java Virtual Machine. RMI programs are
distributed applications that will execute over
different
JVMs running in different address spaces, whether on
the same machine
or another located at a remote
location on the net.

// all Java method invocations between instances
// running on JVMs 'everywhere'

Distributed Object Applications

In RMI, a client will use a local stub object to stand
in as a proxy or surrogate for the remote object. The
remote object will be hosted on an RMI server. The
network transport mechanism, that allows the client
and server to communicate is also supplied by the
RMI system. Because RMI is an object-oriented
distributed system, programs based on RMI , are
also referred to as 'distributed object applications'.

// RMI is based on the Proxy pattern
 

The RMI Application in Detail

We can revisit our earlier RMI example and use it to
point out the salient aspects of an RMI application.
First there is the RMI interface that defines what will
become the remote services.

The Remote Interface

The RMI remote interface is used to declare a set of
methods that will become invocable services on another
Java Virtual Machine. An RMI Remote interface always
extends directly or indirectly the Remote interface that
is defined in the java.rmi package. The java.rmi.Remote
interface is just a marker interface and of itself does not
define any methods.


The Remote interface defined in the java.rmi package

 public interface Remote{  }

// The Remote interface is an empty 'marker' interface

Aside from extending Remote, the method signatures
inside RMI's Remote interface must declare that they
throw the java.rmi.RemoteException.

In the next example though a different interface then we
used in 'HelloRMI' it still has these hallmarks where it
extends the Remote interface and it's methods declare
that they throw java.rmi.RemoteException.
 

RMI Interface Example

public interface Message extends java.rmi.Remote{

   public void setMessage(String message)
                    throws java.rmi.RemoteException
;
   public String getMessages( )
                    throws java.rmi.RemoteException;
   }
 


The RemoteObject Class and its Subclasses

Recall the our earlier example showed the Server's main
method aside
from binding a name to an RMI object and
registering it with a naming service didn't really
do much.
( We did not see sockets creating or connections being
made etc.) That is because the connectivity code is
encapsulated in the
UnicastRemoteObject class which
is extended by our server.

Example

OurServer extends UnicastRemoteObject {  // etc


Remote Object Hierarchy

UnicastRemoteObject is a subclass of RemoteObject
found in the java.rmi.server package. RMI server functions
are provided
by java.rmi.server.RemoteObject and its
subclasses, RemoteServer &
UnicastRemoteObject,
and the java.rmi.activation.Activatable class. Following
is a
diagram of the hierarchy of the RMI server classes.
 

Hierarchy of RMI Service Classes

         java.lang.Object
               |
           RemoteObject
               |
           RemoteServer
               |
Activatable -- + -- UnicastRemoteObject

// Server classses are in java.rmi.server package except for
// Activatable which is in the java.rmi.activation package


RemoteObject

RemoteObject provides implementations for class Object's
methods hashCode( ),
equals( ), and toString( ), in a way
specialized for the RMI environment. The methods
needed
to create and export remote objects are supplied by the
descendent classes
UnicastRemoteObject and Activatable.
 

UnicastRemoteObject & Activatable Classes

UnicastRemoteObject class defines a simple ('unicast')
remote object whose references are valid only while the
server process is
alive. The class Activatable is an
abstract class that can be used to define a service
that
can be activated or instantiated from memory so that
it's remote methods can
be called. Activatable is able
to activate persisted service objects as required. 

We saw in our previous RMI example that the class that
the server was usually an extension of UnicastRemoteObject.
Keep in mind, a remote object may also be an extension of
another class that extends UnicastRemoteObject. Remote
objects might also be extensions of Activatable or an
Activatable subclass as well.

We don't cover Activatable, however the following table
is supplied to facilitate investigation of the class.

 Steps in Running an Activatable Service

Compile stages are similar to using UnicastRemoteObject


ListServ Response 'Registry Persistence',
Moises Lejter
http://archives.java.sun.com/cgi-bin/wa?A2=ind0108&L=rmi-users&P=21673

To run an activatable service:

1. start RMI registry
2. start RMI activation daemon (RMID)
3. run server setup app
4. wait for clients.

At step (3), the server setup app
  (i) creates an activation description,
 
(ii) registers it with RMID and obtains a stub,
  (iii) registers said
stub with RMI registry. 

Once this is all done, server is ready to
activate
the server instances on client demand.

Sun Activation Samples
'Getting Started With RMI'
http://java.sun.com/j2se/1.4.2/docs/guide/rmi/getstart.doc.html


Method and Interface Support in RMI Remote Servers

There is no limit to how many Remote interfaces an
object can implement. As well, Remote objects are
not restricted to providing method implementations for
Remote interfaces only. Implementation classes can
also define their own methods but they are strictly for
local use and have no relationship to the remotely
accessed RMI system.

// an implementation can host any number of remote interfaces
// an implementation can define it's own non-RMI methods


Server Hosting a Remote Implementation Object

In the following server example the second variation
talked about in the preceding note is provided where
the RMI Remote implementation class is defined
separately from the generic server class. The server
class hosts this object.

First we create the implementation class. First the RMI
package imports are supplied. Then we see the extension
of UnicastRemoteObject and the implementation of the
remote interface.

The no-args( ) Constructor

Another key feature to notice at this point is the no-args
constructor that is declared as throwing RemoteException
and invokes it's parent constructor via a call to super( ).
This is an obligatory aspect of an remote implementation
class. If there is any problem creating the remote object,
the constructor will throw the RemoteException that can
be used to process the system failure.

Finally the abstract methods of the remote interface must
be implemented. They are declared as having the potential
to throw RemoteException objects.
 

A Remote Implementation Class Code Sample

import java.util.Vector;
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RMISecurityManager;

public class MessageImpl extends UnicastRemoteObject implements Message{
     
    // 'generics' type declaration as of JDK 1.5
 
    Vector<String> messages;
    String message;

    // the no-args constructor throwing RemoteException 
 
   public MessageImpl( ) throws java.rmi.RemoteException {
     super( );
     messages = new Vector<String>( );
     }
      
      /* remote interface methods  */

public String getMessages( ) throws java.rmi.RemoteException{
     String collection="";
     if (!messages.isEmpty( )){
      for(int i=0; i< messages.size( ); i++){
          collection = collection +  
      ("Message " + ( i + 1 ) + ": \r\n" +
          messages.elementAt(i) +  
          " ~~~~~~~~\r\n");
      }
      // note generic declarations above
      // makes casting unneccessary  \

      messages.clear( );
      return collection;    
    }
    
    else
    {
    return "No messages";
    }
    }

public void  setMessage(String message) throws java.rmi.RemoteException{
   try{
    //  add( ) & addElement( ) yield warning 38: unchecked,
   // unsafe operations without the
'fix', which is add generic
   // syntax supplied in JDK1.5

    messages.add(message);
      }
   catch(Exception e)
      {System.out.println(e);
      }
    }
 }



The RMI Server and Naming Class


Now that the server has passed the RMI service duties
off to the implementation it is obvious it has much less
work to do. Inside main( ), the implementation object is
instantiated and bound to the rmi naming registry via a
static call on the Naming
class method rebind( ). This
publishes the remote service and makes it available
for
remote invocation.

This example shows RMI's native naming service, the
RMI 
registry, called 'rmiregistry' being used. If JNDI
was being used, the code syntax of that registry
would
be used instead.

 

RMI Server Code Sample

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

public class MessageServer {
// no
extends UnicastRemoteObject required
   public static void main(String[] args){
     // System.setSecurityManager(new RMISecurityManager( ));
    try{
       MessageImpl mimple = new MessageImpl( );
       Naming.rebind("memos",mimple);
       }
       catch(Exception e){
       System.out.println
       ("Exception: instantiating & binding the remote");
       }
    }
 }

The Naming Class

The 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:

URL Form of Name Given the Naming Registry

        // 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
that is
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 uses."
                                               - JDK Documentation

// if port is absent RMI's default port is 1099


Details of Binding Names in the Registry

Binding a name for a remote object makes it available
for a lookup at a later time.
Once an object is bound in
the registry, a user can look the object up by name,

obtain a reference on it and then invoke methods on it.
The NotBoundException is
thrown if the name has not
been bound to an object.

Why rebind( )?

The bind( ) method binds the specified name to the
remote object. It throws AlreadyBoundException if
the name
is already bound to an object. To avoid
having the AlreadyBoundException thrown, the rebind( )
method is usually used
instead of the bind( ) method.
The rebind( ) method always binds the name to the

object even if the name is already bound. If this is the
case, the old binding is lost.

// rebind(  ) always binds

There is also an unbind( ) method that will remove a
binding between a name and
an object. The unbind( )
method will throw a NotBoundException if it finds no

binding exists.

The list( ) method can be used to return a 'snapshot' of
the URLs that
are 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

 

Naming Remote Objects & The RMI Registry

Clients locate remote services by using a naming or
directory service. RMI can be used
with a number of
directory services, including JNDI or the Java Naming
& Directory Interface
. RMI itself includes a simple naming
service called the RMI Registry. This
program is invoked
using the executable called 'rmiregistry' at the command
line.

// the RMI registry needs to run on the same machine as the service

JNDI Available For Download

Sun Microsystems has released JNDI as a Java Standard Extension.
Sun Microsystems has also released service providers that plug in seamlessly behind JNDI for a number of naming and directory services: LDAP, NIS, CORBA (COS) Naming, and files. These and service providers produced by other vendors are available for download at
the following link .

http://java.sun.com/products/jndi/serviceproviders.html

This enables you to use a more robust naming registry to be used
with your RMI  program.


Exporting the Remote Object

For security reasons, The RMI registry must be run on
the same machine that is hosting the the remote service
objects. By default
the service is running on port 1099
which is the 'well known' port for RMI. A different
port
can be specified at the command line. The process of
binding an object and
registering it with the directory
service (which we discussed earlier) is also referred
to
as 'exporting' the remote object. By either description
the process involves making
the remote object available
for use by the RMI client.

// 'exporting a remote object refers to binding an object
// by name in a registry, so it can be accessed remotely


The RMI Client


We saw in the example above the rebind( ) method being
used. In the client the naming class is used again to lookup
services that have been registered with the RMI registry.
On the client side, if the standard RMI Registry is being
accessed, the static Naming class is again used, this time
with the method lookup( ). This method 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:


URL form of Remote Reference Used in a Client Lookup

rmi://<host_name> [:<name_service_port>] / <service_name>

//  where the host_name is a name recognized on the local area
// network (LAN) or a
DNS name on the Internet. The name service
// port only needs to be specified only
if the naming service is
// running on a different port  to the default 1099.

Notice in the following client example the lookup( )  method
returns a generic object of type Remote first. This object is
then cast to the name of the remote interface that was used
to create it. In this case the generic remote object is cast to
InCoExchange. The Remote class is somewhat analogous
to the Object class in the regular Java hierarchy of classes.

The elegant aspect of the RMI system is now evident in that
the remote object is now represented by a simple reference
variable which can be used to call the remote methods just
like any other object that has been defined and created locally
on the JVM.
 

RMI Client Setting Messages

// first client inserts message(s)


i
mport java.rmi.*;

public class MessageClientA{
public static void main(String[] args){
  try{
     Remote remote_object=Naming.lookup("//localhost/memos");
     Message messages=(Message)remote_object;

     // setting some messages

     String memo1 = "Dentist: 4:30, Friday July 7.";
     messages.setMessage(memo1);
    
     String memo2 = "Get construction material";
     messages.setMessage(memo2);
                    
   
     }
     catch(Exception e){
     System.out.println
     ("Exception: looking up and accessing the remote");
     }
   }
 }


Second RMI Client Gets Messages

import java.rmi.*;

public class MessageClientB{
public static void main(String[] args){
  try{
     Remote remote_object=Naming.lookup("//localhost/memos");
     Message messages=(Message)remote_object;

         // getting messages
     
     String reminders = messages.getMessages( );
     System.out.println(reminders);
         
     }
     catch(Exception e){
     System.out.println
     ("Exception: looking up and accessing the remote");
     }
   }
 }

// demonstrate at end as a reminder of process
// in context of exercise



Remote Parameter Passing


Parameter Passing Inside The Java Virtual Machine

Recall in a standalone Java program when a parameter
representing a primitive
value is passed to a method, a
copy of the parameter is passed into the method.
When
passing in reference types a copy of the address is
passed in as well (really a pointer) . A
copy of an address,
however, has the same effect as passing in the actual
address.
Both addresses point to the same place. Passing
in reference types is called 'pass by reference'.)
is

In a regular Java program the actual object isn't passed
into the method. The reference suffices because the
method can find the
object somewhere in the shared
address space.

With RMI the situation is more complicated because the
environment is now a
distributed environment consisting
of more then one address space. There are
three types
of parameters that are passed in an RMI system, regular
primitives,
non-RMI objects and RMI objects.

These three types are defined as being serializable or
transferable over a distributed network. RMI remote

and primitive types are treated as being naturally
serializable. Non-RMI reference
type objects must
implement the Serializable interface in order for them
to be
treated as serializable.


Primitve Parameter Passing in RMI

With regular primitive types the procedure RMI takes
is the same as in the
stand-alone environment. That is,
a copy of the primitive is passed into and out
of RMI
remote method calls.

Example    

int i=3.1322;
String dollars = remote.inDollars( i );

// primitive parameters are passed by copy
 

Non-RMI Object Pass in RMI by Serialization

With regular non-RMI object types things are different.
Passing the reference for
such an object is meaningless
as the remote service does not have a representation
of
the object in it's address space. What is required is a
copy of the whole object
needs to be passed over the
network medium to the remote service for processing.

This requires the use of the 'serialization' process where
the object is sent in serial
form with the information
needed to reconstruct the object, and all the state

information as well. Non-RMI objects can converted
into serializable objects by
implementing the Serializable
interface.

In a regular Java program that does not use RMI, the
serialization mechanism can be used
as well. A class
is made serializable by implementing the Serializable
interface. The
ObjectInputStream and ObjectOutputStream
have methods that are then use to
stream the objects.
 

Simple example of a Serializable Object

class Memo implements Serializable{
       String note="Remember the Memo";
        }
 

Sample Code of the Serializable Object written to Stream

import java.io.*;

class Memo implements Serializable{
       String note="Remember the Memo";
        }

class MemoToMemory {
public static void main(String args[]){
   Memo memo=new Memo( );
   System.out.println("Before storing: " + memo.note);
   try{
     // put object to 'sleep'
     ObjectOutputStream oos=new ObjectOutputStream
     (new FileOutputStream("MemoFile"));
     oos.writeObject(memo);
     oos.close();

     // persisted object sleeps for an indefinite time
     // and then is 'reactivated'
    
     ObjectInputStream ois=new ObjectInputStream
     (new FileInputStream("MemoFile"));
     
     Object object = ois.readObject();
     Memo rememo=(Memo)object;
     System.out.println("After sleep: " + rememo.note);     
     }
   catch(ClassNotFoundException cnfe){System.out.println(cnfe);}  
   catch(IOException io)
     { System.out.println("IO Exception");
     }
     }
     }

 
 More on Serialization 

 Using Serialver

 Every serializable object is given a version number. The
 number is referred to as
the SUID, an abbreviation for the
 Stream Unique IDentifier number. This number
is used in
 a protection scheme to keep different versions of the same
 object from
conflicting. The serialver tool reports the version
 number which is
represented as a constant of long type for
 the object.

 If a new version of a serializable object needs to
 be created to replace an old one the same number
can be
 assigned
explicitly so as to hide and effectively mask the
 newer unique
identifier that would be created for the new
 serializable object. 

C:\NewCode\RMI>serialver Memo
 Memo: static final long serialVersionUID = -2776950940961670497L;
 


RMI Remote Object Passing

RMI remote objects on the other hand have representation
on remote machines. In
the case where an object belonging
to the RMI system is passed over the network
the whole
object does not need to be passed. When an RMI object
is sent or returned as a parameter of a method, sends a
'stub' or
'proxy' for the object to act as a reference for the
RMI remote object. 

// RMI Remote Object stubs are to be distinguished
// from the Transport Stub

There is a restiction on passing RMI remote objects. A
remote object passed as a parameter can only implement
remote interfaces. All this activity is hidden away in the
Remote
Reference Layer and so are not visible to the RMI
developer.

 

Class Annotation

One of the key mechanisms used in the RMI system is
class annotation. When an
object is sent from one virtual
machine to another in a remote method call, the
RMI
system annotates the class descriptor in the call stream
with a URL describing
where the class can be found and
loaded from by the receiving JVM. This is part
of the RMI
system's communication scheme where classes can be
loaded on
demand from a variety of sources.

// class annotation --> where the class can be found & loaded

Parameter Transmission

RMI uses a subclass of ObjectOutputStream which is
found in the java.io package, to serialize parameters to
stream. If a standard non-RMI object is being sent, the
writeObject( ) method is used. Otherwise, if it is an RMI
remote object, the replaceObject( ) method is used in
conjunction with static toStub( ) method of RemoteObject
to send the stub for the RMI remote object.


Stubs ( & Skeletons ) Activities

Below the parameter passing level, the Stubs  (and
for older JDKs, Skeletons) make use of TCP/IP sockets
to make network connections. When a stub's method is
invoked, the stub takes care of the following functions.


(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 code encapsulates the Remote Reference layer
and the Stub & Skeleton transmission layers, hiding all
these details from the RMI developer and user. The
skeleton ( or equivalent code in newer versions) receiving
an incoming method invocation will carry out the following
steps.

(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


As mentioned before the newer version of RMI contained in
JDK1.2 and later, adds
additional, stub protocol code that
allows the skeleton code to be eliminated
from the system.
 

Using exportObject( ) method 
// provides  two-way remote calling

Sometimes a server may which to make a 'return call'
or a what is popularly called a 'call back' to a client. In
this case the client will need to act as an RMI server.
This would involve extending UnicastRemoteObject (or
perhaps it's relative, Activatable) and providing a naming
service. This may not be practical as the client may not
be suited to act as a server.

RMI supplies the exportObject( ) method that the client
can use to send the server a remote object to call
methods back on the client. This is a static method
of the UnicastRemoteObject class that may be called
as shown in the example below.


Example  

UnicastRemoteObject.exportObject (remote_object);

// a client may use the static exportObject( ) to
// make
an object available for a Server to call


Distributing RMI Classes


To run an RMI application, the supporting class files must
be placed in locations that can be found by the server and
the clients. For the server, the following classes must be
available to its class loader:

Server Class Requirements


For the client, the following classes must be available to its
class loader:

Client Class Requirements


Automatic Distribution of Classes & the RMIClassLoader

Different Class Loaders

Java has different class loaders. Which works depends on
the environment in which they are used. The standard Java
class loader is called simply ClassLoader. Applets use
AppletClassLoader. RMI has special requirements for it's
class loader, being required to load classes from different
locations distributed over an network. The RMI class
loader is called the RMIClassLoader.

As noted above, RMI requires all the class definitions
it needs to work to be available. The RMIClassLoader
works with the SecurityManager class object to create
a complex and dynamic class loading system. The
design permits loading classes from different types of
servers such as FTP and HTTP servers.

The design allows classes to be centrally located in
one or two places for an entire distributed system. The
RMIClassLoader can be controlled by using a set of
properties that are specified when the Java Virtual
Machine is started. Following is the format that is
followed to specify the properties.


Form to Set Codebase for JVM

 java[ -D<PropertyName>=<PropertyValue> ] + <ClassFile>

The 'java.rmi.server.codebase' Property

The 'java.rmi.server.codebase' property can be used to
specify a URL for servers
from which class files can be
loaded. Such servers may be using the File, FTP or

HTTP protocols. RMI does not send class files along
with the serialized objects.
Instead the JVM looks for
the embedded URL that describes the class that was

annotated in the serialization stream. (This is the same
class annotation process
we mentioned earlier.) The
JVM will then obtain the file from the server that is

described by the annotated URL.

The  'java.rmi.server.useCodebaseOnly' Property

The property 'java.rmi.server.useCodebaseOnly' can be
set to true to restrict the JVM to loading classes from
either a location specified by the CLASSPATH variable
or a URL specified in this property. By using different
combinations of the available system properties, a number
of different RMI system configurations can be created as
described in the RMI tutorial found at the Sun site entitled,
'Fundamentals of RMI tutorial', written by Govind Seshadri.

// URL active as of June 2006


Variations on Class Distribution Schemes for RMI
Systems

Closed - A Closed System describes the scenario when
all the c
lasses used by clients and the server are located
on the Java Virtual Machine and are referenced by the
CLASSPATH environment variable. No dynamic class
loading is supported in this configuration.

// all classes available locally, no dynamic loading

Server Based - In a server based system Java applets
are used in conjunction with RMI. This allows the applet
code and all associated RMI classes to be loaded from
the server's CODEBASE.

// all classes loaded from server's codebase

Client Dynamic - The tutorial above uses the 'Client
Dynamic' term to describe a system
where the primary
classes are loaded by referencing the client JVM,
CLASSPATH environment variable. Other supporting
classes are loaded by the server's RMIClassLoader at
a location specified by the server, either from an HTTP
or
FTP network location. ( Classes are loaded at the
Client and otherwise undergo dynamic loading at the
server. )

// class loading is initiated on the client and further
// loading is done by server from a network location

Server Dynamic In the Server Dynamic model the
primary classes are loaded by referencing the CLASSPATH
environment variable of the JVM for the server. Supporting
classes are loaded by the java.rmi.server.RMIClassLoader
from an
HTTP or FTP server on the network at a location
specified by the client.

// the server initiates class loading and the client loads
// additional classes dynamically from a network location

Bootstrap Client - In the BootStrap configuration, all of
the client code is loaded from an HTTP or FTP server
across the network. All the client stores is a short program
called the 'bootstrap loader' has enough code to make a
call that starts the loading process.

// all client code is loaded from a network server

Bootstrap Server - In BootStrap Server configuration,
all of the server code is loaded from an HTTP or FTP
server located on the network. The only code residing
on the server machine is a small bootstrap loader.

//  a small bootstrap loader initiates loading all server
// code from a network server


RMISocketFactory & Firewall Issues


The JDK documentation gives an insight into how RMI
systems go about making connections. Inside the stub
code a Java class called the RMISocketFactory is used
to obtain client and server sockets for needed to make
RMI remote method calls. By default the socket factory
has a three-tiered strategy to making client socket
connections.

First, a conventional socket connection to the remote
JVM is attempted. If action is impeded by the presence
of a firewall, then the RMI runtime uses the Hypertext
Transfer Protocol to try to connect to the server. If the
firewall does not allow this type of communication, then
a CGI-bin script via HTTP is used to POST the RMI call.
This 'HTTP tunneling' comes with a significant
performance loss.

// three tiered connection strategy starts with a regular RMI
// connection, then trys a HTTP connection and finally an
// HTTP POST via a cgi-script

Using the Java-RMI CGI script exposes a security risk as
the script can
be used to redirect any incoming request to
any port bypassing the firewall entirely.
For these and other
reasons it may be better to disable the HTTP tunneling
feature or the socket factory. This is done by setting the
java.rmi.server.disableHttp property to 'true' as is shown
in the following example.

Example      

java.rmi.server.disableHttp=true


Self Test                          Self Test With Answers


1) Which of the following statements is not correct?

a) The rmi Remote interface declares a single method that must be implemented.
b) To use rmi begins with implementing the Remote interface
c) The Remote interface is in the java.rmi package
d) Methods declared inside the remote method be declared as throwing
    rmi's RemoteException exception.

2) Which is the top level class of the following?

a) UnicastRemoteObject
b) Activatable
c) RemoteServer
d) RemoteObject

3) Which of the following is not a key feature of the rmi implementation class.

a) A no-args constructor that throws RemoteException
b) an extension of a RemoteServer subclass
c) The implementation class will implement Remote interface.
d) Remote methods are defined in the implementation class

4) The RMI Server does all but one of the following.

a) may set the SecurityManager
b) Instantiates the remote object implementation
c) binds the object to a name in the the naming service
d) catches for RemoteException

5) RMI cannot pass which of the following objects?

a) primitive types
b) remote objects
c) class objects that are not extensions or implementations of any interfaces
d) class objects that implement serializable

6) The codebase attributes of different JVMs can be used
in combination with loading classes in the regular CLASSPATH
to create various paths to classes needed by the RMI system.
Which of the following systems as described in G. Seshadri's
RMI tutorial represents the least dynamic system regarding
class
loading.

a) Closed
b) Server Based
c) Client Dynamic
d) Client Bootstrap


Exercise

1) Create a Remote Interface with Three Methods

Using the RMI examples from the previous two notes,
create a complete RMI program that will provide three
functions that describe the services of three floors of
a department store. Alternatively a brief description
can be provided for three departments of a company.

These three methods will be  first  provided as  abstract
methods in an RMI Remote interface. Name the RMI
Remote interface appropriately to relate to the service
provided by the methods.

// provide RMI extensions and have methods throws RMI exceptions.

2) Create a Remote Implementation class

Create an RMI implementation class that supplies
implementations for the three methods. Again keep
the name of the implementation related to the service.
The methods should each return a String that holds
the description of the floor or department.

// provide the appropriate RMI extensions and implement
// the RMI Remote defined above

3) Create a server that hosts the implementation class

Create a Server named appropriately that instantiates
the implementation class you have created and binds
the service to a name in the RMI naming service.

4) Create a Client that acessesses the Remote Services

// will do appropriate lookups

5) Compile with javac and rmic as needed. Run the system
and submit code and screen shots of the service output from
the client's DOS window.

OR

Do all the above however create a Service that relates to
a topic of interest to you.

OR

Use the exportObject( ) method to send a server an object
that can be used to get info back to the server from the
object. Location and Time information would be candidates
to return to a server that has been accessed.