-
Language:
English
-
Language:
English
Red Hat Training
A Red Hat training course is available for JBoss Enterprise Application Platform Common Criteria Certification
Chapter 6. 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/IncomingOrders
and 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
ProductCatalog
session 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.
6.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.naming
package. It contains five interfaces, 10 classes, and several exceptions. There is one key class, InitialContext
, and two key interfaces, Context
and Name
6.1.1. Names
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.txt
in 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.
The
javax.naming.Name
interface 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.txt
to the file remotefile.txt
in the tmp
directory on host ahost.someorg.org
:
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.txt
is a composite name that spans the DNS and Unix file system namespaces. The components of the composite name are ahost.someorg.org
and /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.CompoundName
class. The JNDI API provides the javax.naming.CompositeName
class as the implementation of the Name
interface for composite names.
6.1.2. Contexts
The
javax.naming.Context
interface is the primary interface for interacting with a naming service. The Context
interface 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.Name
instances. To create a name-to-object binding you invoke the bind method of a Context
and specify a name and an object as arguments. The object can later be retrieved using its name using the Context
lookup method. A Context
will 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 Context
can itself be of type Context
. The Context
object that is bound is referred to as a subcontext of the Context
on 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 /usr/jboss
names a jboss
context 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 jboss
is a subcontext of org
because DNS names are parsed right to left.
6.1.2.1. Obtaining a Context using InitialContext
All naming service operations are performed on some implementation of the
Context
interface. Therefore, you need a way to obtain a Context
for the naming service you are interested in using. The javax.naming.IntialContext
class implements the Context
interface, 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.
- All
jndi.properties
resource 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.properties
file, 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.
The
Context
implementation used internally by the InitialContext
class 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.InitialContextFactory
implementation. You obtain the name of the InitialContextFactory
class from the naming service provider you are using.
Example 6.1, “A sample jndi.properties file” gives a sample
jndi.properties
file 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.properties
file 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 6.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