JNDI: Java's Naming Service

A naming service is an integral piece of distributed systems. With the explosion of the Internet, naming services have become commonplace. While computers communicate with raw IP addresses such as 198.137.241.43, humans prefer symbolic names such as whitehouse.gov. Naming is not only a convenience for humans: It also adds a level of indirection. If the user always uses the whitehouse.gov name, the mapping of the name to a raw address can change without breaking a client.

The naming service is also location-independent. For instance, an email about the latest foreign policy might indicate that more information can be found on whitehouse.gov. The name whitehouse.gov is independent of the client; anyone can use the name to locate the Web page.

Like the Internet, distributed Java programs require a naming service to locate distributed objects. JavaSoft has defined the JNDI as Java's standard naming service. JNDI enables servers to host objects at specified names. Remote clients can perform a lookup in the JNDI service and receive a reference to the specified object.

The JNDI architecture consists of a common client interface and a set of JNDI providers that define the back-end naming system. JavaSoft defines an SPI interface through which new JNDI providers can be plugged into the JNDI system. Implementing a JNDI provider is not terribly difficult, but it is beyond the scope of this book. Instead, we cover the WebLogic implementation of JNDI and how a user program makes use of the JNDI system.

Using JNDI

A JNDI client interacts with the JNDI system through the classes in the javax.naming package. The javax.naming.Context interface is the fundamental JNDI object. The Context interface has methods for a client to add, remove, and look up objects in the naming service.

The javax.naming.InitialContext class implements the Context interface. Clients use this class to interact with the JNDI system. Clients create an InitialContext object with the code snippet:

Context ctx = new InitialContext();

When the InitialContext method is created in the WebLogic server, the caller receives an InitialContext that references the JNDI service on the local server. Remote clients can also create InitialContext references, but a client must let the JNDI client know the location of the WebLogic Server. One way to accomplish this is to explicitly pass a Properties object to the InitialContext constructor:

java.util.Properties p = new java.util.Properties();p.put(Con-
text.INITIAL_CONTEXT_FACTORY,          "weblogic.jndi.WLInitial-
ContextFactory");p.put(Context.PROVIDER_URL, "t3://
revere:7001");

Context ctx = new InitialContext(p);

In this example, we create a Properties object, specify that WebLogic Server is the JNDI provider, and give the URL to the server. For example, in this case we are creating a connection to the machine named “revere” on port 7001.

It is important to note that the PROVIDER_URL should only be set when connecting to a naming service that is not running in the local Java virtual machine (JVM).

For instance, a client that is connecting to a WebLogic Server uses the PROVIDER_URL to indicate which WebLogic Server or cluster to use. It is also possible for a WebLogic Server to be a client of another WebLogic Server or another JNDI provider.

This commonly occurs when a servlet engine looks up EJBs deployed in another WebLogic Server instance. When the JNDI lookup occurs in the servlet engine, it will provide the PROVIDER_URL of the target EJB server.

However, the PROVIDER_URL should not be specified when code running in the server is connecting to the local naming service. The PROVIDER_URL indicates that a network connection should be made. This is unnecessary when the naming service is running within the same WebLogic Server instance as the calling code. Also, server-side code such as WebLogic start-up classes run before the server has begun listening for network connections. Server-side code should use new InitialContext() to connect to the local naming service.


It is also possible for clients to use the default constructor to gain InitialContexts, for example:

Context ctx = new InitialContext();

In this case, the client needs to specify the provider and URL with other methods. One option is to define the Java properties on the command line with:

-Djava.naming.factory.initial=weblogic.jndi.WLInitialContextFac-
tory

and

-Djava.naming.provider.url="t3://revere:7001"

Another possibility is to specify the factory and the URL in a jndi.properties file. This properties file is a Java resource file. For instance, our jndi.properties file would contain:

java.naming.factory.initial=weblogic.jndi.WLInitialContextFacto-
ryjava.naming.provider.url="t3://revere:7001"

In general, it is preferable to use the default InitialContext constructor in all cases. For stand-alone clients, the jndi.properties file is the preferred method to specify the attributes.


With the InitialContext object, the JNDI client can store objects in the naming system. Like RMI parameters, an object stored in JNDI must either implement java.io.Serializable or java.rmi.Remote. The bind method of the InitialContext object is used to establish a name to object mapping in the JNDI tree. For instance, this example binds a String object to the name "Chapter6".

Context ctx = new InitialContext();

String s = "Test String.";

ctx.bind("Chapter6", s);

The bind call establishes a mapping between the name Chapter6 and our string. Clients can now look up the name Chapter6 in the WebLogic Server's JNDI system and receive a copy of our string. The bind call fails if an object named "Chapter 6" already exists in this JNDI tree.

The rebind call can be used to reassign an already existing name. If there is no current mapping for the given name, rebind behaves like bind.

Context ctx = new InitialContext();

String s = "New Test String.";

ctx.rebind("Chapter6", s);

Mappings can be deleted with the unbind method. For instance, the following code fragment removes the object we just bound:

ctx.unbind("Chapter6");

A client uses the InitialContext's lookup method to get a reference to an object in the naming service. For instance, after our call to bind there is a mapping from the name "Chapter6" to our string. The client can get a reference to this object with:

Context ctx = new InitialContext();

String s = (String) ctx.lookup("Chapter6");

Because java.lang.String is a serializable object, the client receives a copy of the bound object. If this had been an RMI object, the client would have received a stub.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.248.37