The naming service maintains a set of bindings, which relate names to objects. Binding an object means adding a name to the naming service and associating that name with a Java object.
JNDI Registry Service functionality can be used for storing and locating resources by server-side components and applications as well as standalone remote clients.
Depending on the type of objects (serializable; nonserializable, or remote) that are stored, the result from the bind and lookup operations in the naming system varies for the different types of clients.
You have obtained an initial context instance.
Use one of the following methods to associate an object to a name:
● Context.bind()
● Context.rebind()
and one of the following methods to associate the object to a set of attributes and a name:
● DirContext.bind()
● DirContext.rebind()
If there is an object already associated with the name specified as the method parameter, the bind () method throws NameAlreadyBoundException, while the rebind () method replaces the existing binding with the new object provided.
If you want to remove a binding, use the unbind() method.
Depending on the object type passed as a method argument, the underlying naming system represents the object instance in a way that is suitable for storing it in the memory repository.
JNDI Registry Service provides different handling and support for each of the three different types of objects:
try { // create InitialContext to access JNDI Registry Service naming system. // InitialContext creation depends on the type of the client Context ctx = new InitialContext();
// Create instance of the object you want to bind Object serialObj = "Strings are serializable objects";
// define name to associate the object with String name = "serializable_binding";
// use bind or rebind method to associate the object with the name ctx.bind(name, serialObj);
System.out.println("Bound object [" + serialObj + "] to name [" + name + "]"); } catch (NamingException e) { e.printStackTrace } |
The object passed to the bind () method is serializable. No matter if the client is running on the server process or if it is a standalone application, the object is serialized to byte array; sent to the server process (in case of an external standalone client) and stored in the JNDI Registry Service repository. Then, this object becomes available for lookup with the name specified from any client.
External clients that look up this object should have its class definition and the classes referred by it in their class path to perform successful deserialization of the object.
More information about serializable objects:
http://java.sun.com/products/jndi/tutorial/objects/storing/serial.html
Remote objects can be made available to applications running on foreign JVMs by binding them in the JNDI Registry Service naming system. If a server-side component binds a remote object with a name in the JNDI Registry Service, any standalone application running on a foreign JVM can look up that object by name; get a reference to it called a stub, and invoke methods on the stub that will be executed on the server-side JVM where the object implementation resides.
//For the remote object implementation we need a remote interface which extends //java.rmi.Remote interface.
public interface Timer extends Remote { public String getTime() throws RemoteException; }
// The remote object implementation follows. public class TimerImpl implements Timer { public TimerImpl() throws RemoteException { }
public String getTime() throws RemoteException { return (new java.util.Date()).toString(); } }
//The next step is to create an instance of the remote object and bind it with a //name in the naming system. try { // create InitialContext to access JNDI Registry Service naming system. // InitialContext creation depends on the type of the client Context ctx = new InitialContext();
// Create instance of the object you want to bind Timer timer = new TimerImpl();
// define name to associate the object with String name = "remote_timer";
// use bind or rebind method to associate the object with the name ctx.bind(name, timer);
System.out.println("Bound object [" + timer + "] to name [" + name + "]"); } catch (NamingException e) { e.printStackTrace(); } |
When the object bound is a remote one, its implementation stays on the JVM of the application that created an instance and bound it in the naming service.
It is not sent to the server process where the JNDI Registry Service repository resides in case of external client usage. Only connection information for the client JVM is sent to the JNDI Registry Service repository so that with a lookup operation, the remote protocol is able to connect the stub to the remote implementation. The default remote protocol used by JNDI Registry Service is P4.
The most common case is when the remote object implementation is provided by a server-side client and looked up by external standalone clients or applications running in foreign AS Java clusters. In this case, remote clients invoke methods on the stub returned by the lookup operation which are executed on the server process where the object implementation is provided.
To look up such an object from a remote JVM, you must have the remote interface of this object in the class path.
try { // create InitialContext to access JNDI Registry Service naming system. // InitialContext creation depends on the type of the client Context ctx = new InitialContext();
// Create instance of the object you want to bind Object nonSerialObj = new Object();
// define name to associate the object with String name = "non_serializable_binding";
// use bind or rebind method to associate the object with the name ctx.bind(name, nonSerialObj);
System.out.println("Bound object [" + nonSerialObj + "] to name [" + name + "]"); } catch (NamingException e) { e.printStackTrace(); } |
If a nonserializable object is bound by a server-side component, it is not visible outside of the server process, that is, no external standalone client will be able to look it up.