Show Table of Contents
Chapter 9. The JNDI Naming Service
The naming service plays a key role in enterprise Java applications, providing the core infrastructure that is used to locate objects or services in an application server. It is also the mechanism that clients external to the application server use to locate services inside the application server. Application code, whether it is internal or external to the JBoss Enterprise Application Platform instance, needs only know that it needs to talk to the a message queue named
queue/IncomingOrdersand need not worry about any of the queue's configuration details.
In a clustered environment, naming services are even more valuable. A client of a service must be able to look up a
ProductCatalogsession bean from the cluster without needing to know which machine it resides on. Whether it is a large clustered service, a local resource or an application component that is needed, the JNDI naming service provides the glue that lets code find the objects in the system by name.
9.1. An Overview of JNDI
JNDI is a standard Java API that is bundled with the Java Development Kit. JNDI provides a common interface to a variety of existing naming services: DNS, LDAP, Active Directory, RMI registry, COS registry, NIS, and file systems. The JNDI API is divided logically into a client API that is used to access naming services, and a service provider interface (SPI) that allows the user to create JNDI implementations for naming services.
The SPI layer is an abstraction that naming service providers must implement to enable the core JNDI classes to expose the naming service using the common JNDI client interface. An implementation of JNDI for a naming service is referred to as a JNDI provider. JBoss naming is an example JNDI implementation, based on the SPI classes. Note that the JNDI SPI is not needed by J2EE component developers.
The main JNDI API package is the
javax.namingpackage. It contains five interfaces, 10 classes, and several exceptions. There is one key class,
InitialContext, and two key interfaces,
The notion of a name is of fundamental importance in JNDI. The naming system determines the syntax that the name must follow. The syntax of the naming system allows the user to parse string representations of names into its components. A name is used with a naming system to locate objects. In the simplest sense, a naming system is just a collection of objects with unique names. To locate an object in a naming system you provide a name to the naming system, and the naming system returns the object store under the name.
As an example, consider the Unix file system's naming convention. Each file is named from its path relative to the root of the file system, with each component in the path separated by the forward slash character ("
/"). The file's path is ordered from left to right. The pathname
/usr/jboss/readme.txt, for example, names a file
readme.txtin the directory
jboss, under the directory
usr, located in the root of the file system. JBoss Enterprise Application Platform naming uses a Unix-style namespace as its naming convention.
javax.naming.Nameinterface represents a generic name as an ordered sequence of components. It can be a composite name (one that spans multiple namespaces), or a compound name (one that is used within a single hierarchical naming system). The components of a name are numbered. The indexes of a name with N components range from 0 up to, but not including, N. The most significant component is at index 0. An empty name has no components.
A composite name is a sequence of component names that span multiple namespaces. An example of a composite name would be the hostname and file combination commonly used with Unix commands like
scp. For example, the following command copies
localfile.txtto the file
tmpdirectory on host
scp localfile.txt ahost.someorg.org:/tmp/remotefile.txt
A compound name is derived from a hierarchical namespace. Each component in a compound name is an atomic name, meaning a string that cannot be parsed into smaller components. A file pathname in the Unix file system is an example of a compound name.
ahost.someorg.org:/tmp/remotefile.txtis a composite name that spans the DNS and Unix file system namespaces. The components of the composite name are
/tmp/remotefile.txt. A component is a string name from the namespace of a naming system. If the component comes from a hierarchical namespace, that component can be further parsed into its atomic parts by using the
javax.naming.CompoundNameclass. The JNDI API provides the
javax.naming.CompositeNameclass as the implementation of the
Nameinterface for composite names.
javax.naming.Contextinterface is the primary interface for interacting with a naming service. The
Contextinterface represents a set of name-to-object bindings. Every context has an associated naming convention that determines how the context parses string names into
javax.naming.Nameinstances. To create a name-to-object binding you invoke the bind method of a
Contextand specify a name and an object as arguments. The object can later be retrieved using its name using the
Contextlookup method. A
Contextwill typically provide operations for binding a name to an object, unbinding a name, and obtaining a listing of all name-to-object bindings. The object you bind into a
Contextcan itself be of type
Contextobject that is bound is referred to as a subcontext of the
Contexton which the bind method was invoked.
As an example, consider a file directory with a pathname
/usr, which is a context in the Unix file system. A file directory named relative to another file directory is a subcontext (commonly referred to as a subdirectory). A file directory with a pathname
jbosscontext that is a subcontext of
usr. In another example, a DNS domain, such as
org, is a context. A DNS domain named relative to another DNS domain is another example of a subcontext. In the DNS domain
jboss.org, the DNS domain
jbossis a subcontext of
orgbecause DNS names are parsed right to left.
220.127.116.11. Obtaining a Context using InitialContext
All naming service operations are performed on some implementation of the
Contextinterface. Therefore, you need a way to obtain a
Contextfor the naming service you are interested in using. The
javax.naming.IntialContextclass implements the
Contextinterface, and provides the starting point for interacting with a naming service.
When you create an
InitialContext, it is initialized with properties from the environment. JNDI determines each property's value by merging the values from the following two sources, in order.
- The first occurrence of the property from the constructor's environment parameter and (for appropriate properties) the applet parameters and system properties.
jndi.propertiesresource files found on the classpath.
For each property found in both of these two sources, the property's value is determined as follows. If the property is one of the standard JNDI properties that specify a list of JNDI factories, all of the values are concatenated into a single colon-separated list. For other properties, only the first value found is used. The preferred method of specifying the JNDI environment properties is through a
jndi.propertiesfile, which allows your code to externalize the JNDI provider specific information so that changing JNDI providers will not require changes to your code or recompilation.
Contextimplementation used internally by the
InitialContextclass is determined at runtime. The default policy uses the environment property
java.naming.factory.initial, which contains the class name of the
javax.naming.spi.InitialContextFactoryimplementation. You obtain the name of the
InitialContextFactoryclass from the naming service provider you are using.
Example 9.1, “A sample jndi.properties file” gives a sample
jndi.propertiesfile a client application would use to connect to a JBossNS service running on the local host at port 1099. The client application would need to have the
jndi.propertiesfile available on the application classpath. These are the properties that the JBossNS JNDI implementation requires. Other JNDI providers will have different properties and values.
Example 9.1. A sample jndi.properties file
### JBossNS properties java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=jnp://localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces