New York University

Computer Science Department

Courant Institute of Mathematical Sciences

 

The RMI Naming Service

 

Course Title: Application Servers                                           Course Number: g22.3033-011

Instructor: Jean-Claude Franchitti                                            Session: 5

 

 

The RMI system uses the java.rmi.registry.Registry interface and the java.rmi.registry.LocateRegistry class to provide a well-known bootstrap service for retrieving and registering objects by simple names.

A registry is a remote object that maps names to remote objects. Any server process can support its own registry or a single registry can be used for a host.

The methods of LocateRegistry are used to get a registry operating on a particular host or host and port. The methods of the java.rmi.Naming class makes calls to a remote object that implements the Registry interface using the appropriate LocateRegistry.getRegistry method.

 

I. The Naming Class

The java.rmi.Naming class provides methods for storing and obtaining references to remote objects in the remote object registry. The Naming class's methods take, as one of their arguments, a name that is 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's 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. A registry may be shared by all servers running on a host or an individual server process may create and use its own registry if desired (see java.rmi.registry.LocateRegistry.createRegistry method for details).

package java.rmi;

public final class Naming {

     public static Remote lookup(String url)

                throwsNotBoundException, java.net.MalformedURLException,

             RemoteException;

     public static void bind(String url, Remote obj)

             throws AlreadyBoundException,

             java.net.MalformedURLException, RemoteException;       

     public static void rebind(String url, Remote obj)

             throws RemoteException,

 java.net.MalformedURLException;

     public static void unbind(String url)

             throws RemoteException, NotBoundException,

             java.net.MalformedURLException;

     public static String[] list(String url)

             throws RemoteException,

 java.net.MalformedURLException;

}

 

 

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.

 


Note - The java.rmi.AccessException may also be thrown as a result of any of these methods. The AccessException indicates that the caller does not have permission to execute the specific operation. For example, only clients that are local to the host on which the registry runs are permitted to execute the operations, bind, rebind, and unbind. A lookup operation, however can be invoked from any non-local client.

 


II. The Registry Interface

The java.rmi.registry.Registry remote interface provides methods for lookup, binding, rebinding, unbinding, and listing the contents of a registry. The java.rmi.Naming class uses the registry remote interface to provide URL-based naming.

package java.rmi.registry;

 

public interface Registry extends java.rmi.Remote {

     public static final int REGISTRY_PORT = 1099;

     public java.rmi.Remote lookup(String name)

             throws java.rmi.RemoteException,

             java.rmi.NotBoundException, java.rmi.AccessException;

     public void bind(String name, java.rmi.Remote obj)

             throws java.rmi.RemoteException,

             java.rmi.AlreadyBoundException, java.rmi.AccessException;

     public void rebind(String name, java.rmi.Remote obj)

             throws java.rmi.RemoteException, java.rmi.AccessException;

     public void unbind(String name)

             throws java.rmi.RemoteException,

             java.rmi.NotBoundException, java.rmi.AccessException;

     public String[] list()

             throws java.rmi.RemoteException, java.rmi.AccessException;

}

 

 

The REGISTRY_PORT is the default port of the registry.

The lookup method returns the remote object bound to the specified name. The remote object implements a set of remote interfaces. Clients can cast the remote object to the expected remote interface. (This cast can fail in the usual ways that casts can fail in the Java language.)

The bind method associates the name with the remote object, obj. If the name is already bound to an object the AlreadyBoundExcepton is thrown.

The rebind method associates the name with the remote object, obj. Any previous binding of the name is discarded.

The unbind method removes the binding between the name and the remote object, obj. If the name is not already bound to an object the NotBoundException is thrown.

The list method returns an array of Strings containing a snapshot of the names bound in the registry. The return value contains a snapshot of the contents of the registry.

Clients can access the registry either by using the LocateRegistry and Registry interfaces or by using the methods of the URL-based java.rmi.Naming class. The registry supports bind, unbind, and rebind only from clients on the same host as the server; a lookup can be done from any host.



III. The LocateRegistry Class

The class java.rmi.registry.LocateRegistry is used to obtain a reference (construct a stub) to a bootstrap remote object registry on a particular host (including the local host), or to create a remote object regsitry that accepts calls on a specific port.

The registry implements a simple flat naming syntax that associates the name of a remote object (a string) with a remote object reference. The name and remote object bindings are not remembered across server restarts.

Note that a getRegistry call does not actually make a connection to the remote host. It simply creates a local reference to the remote registry and will succeed even if no registry is running on the remote host. Therefore, a subsequent method invocation to a remote registry return as a result of this method may fail.

package java.rmi.registry;

public final class LocateRegistry {

     public static Registry getRegistry()

             throws java.rmi.RemoteException;

     public static Registry getRegistry(int port)

             throws java.rmi.RemoteException;

     public static Registry getRegistry(String host)

             throws java.rmi.RemoteException;

     public static Registry getRegistry(String host, int port)

             throws java.rmi.RemoteException;

     public static Registry getRegistry(String host, int port,

RMIClientSocketFactory csf)

             throws RemoteException;

     public static Registry createRegistry(int port)

             throws java.rmi.RemoteException;

     public static Registry createRegistry(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf)

             throws RemoteException;

}

 

 

The first four getRegistry methods return a reference to a registry on the current host, current host at a specified port, a specified host, or at a particular port on a specified host. What is returned is the remote stub for the registry with the specified host and port information.

The fifth getRegistry method (that takes an RMIClientSocketFactory as one of its arguments), returns a locally created remote stub to the remote object Registry on the specified host and port. Communication with the remote registry whose stub is constructed with this method will use the supplied RMIClientSocketFactory, csf, to create Socket connections to the registry on the remote host and port.

 


Note - A registry returned from the getRegistry methods is a specially constructed stub that contains a well-known object identifier. Passing a registry stub from one VM to another is not supported (it may or may not work depending on the implementation). Use the LocateRegistry.getRegistry methods to obtain the appropriate registry for a host.

 


The createRegistry methods creates and exports a registry on the local host on the specified port.

The second createRegistry method allows more flexiblity in communicating with the registry. This call creates and exports a Registry on the local host that uses custom socket factories for communication with that registry. The registry that is created listens for incoming requests on the given port using a ServerSocket created from the supplied RMIServerSocketFactory. A client that receives a reference to this registry will use a Socket created from the supplied RMIClientSocketFactory.

 


Note - Starting a registry with the createRegistry method does not keep the server process alive.

 




IV. The RegistryHandler Interface

 


Note - The RegistryHandler interface is deprecated in JDK1.2. In JDK1.1, it was only used internally by the RMI implementation and was not for application use.

 


package java.rmi.registry;

 

public interface RegistryHandler {

     Registry registryStub(String host, int port)

             throws java.rmi.RemoteException,

             java.rmi.UnknownHostException;

     Registry registryImpl(int port)

             throws java.rmi.RemoteException;

}

 

 

The method registryStub returns a stub for contacting a remote registry on the specified host and port.

The method registryImpl constructs and exports a registry on the specified port. The port must be nonzero.