Previous | Next | Trail Map | Beyond the Basics | URLs

URLs as Names to the Initial Context

In the JNDI, every name is resolved relative to a context. To begin, you typically create an initial context by using one of the constructors from the InitialContext(in the API reference documentation), InitialDirContext(in the API reference documentation), or InitialLdapContext(in the API reference documentation) class. The Environment Properties (in the Beyond the Basics trail) lesson contains examples of how to use these constructors.

Once you have an instance of a Context(in the API reference documentation), you can look up other contexts and perform naming operations relative to those contexts. The names supplied to all of these contexts are relative names. That is, they are interpreted relative to the context to which they are supplied.

The closest thing to an absolute name in the JNDI is a URL string. In the JNDI, you can supply a URL string to the methods in the InitialContext and InitialDirContext classes. (The InitialLdapContext class does not declare any method that accepts a name argument, although the class does inherit all of the methods from the InitialContext and InitialDirContext classes.)

Client's View

When you supply a URL string, that is, a string of the form
scheme : scheme-specific-parts
to an InitialContext or InitialDirContext method, such as lookup()(in the API reference documentation), the name is treated as a URL string rather than a name relative to the initial context. Here is an example that looks up an object using an LDAP URL string.
Object obj = new InitialContext().lookup(
    "ldap://localhost:389/cn=homedir,cn=Jon%20Ruiz,ou=People,o=jnditutorial");

The InitialContext class (and subclasses) diverts the method invocation so that it is processed by the corresponding URL context implementation rather than any underlying initial context implementation. That is, if you had set the Context.INITIAL_CONTEXT_FACTORY(in the API reference documentation) environment property, then it would not have been used in the lookup() call. Instead, the JNDI would find and use the URL context implementation for the ldap URL scheme. Notice from the previous example that no Context.INITIAL_CONTEXT_FACTORY property was specified to the InitialContext constructor.

The JNDI's ability to accept arbitrary URL strings from the InitialContext class (and subclasses) allows you to access any namespace for which you have an implementation. Thus, you are not restricted by the namespace offered by the implementation named by the Context.INITIAL_CONTEXT_FACTORY property. For example, suppose that you name a file system service provider by using the Context.INITIAL_CONTEXT_FACTORY environment property. Using the same InitialContext instance, you can access an LDAP namespace by specifying an LDAP URL string and you can access a CORBA namespace by specifying a CORBA URL string.

How URL Strings Are Processed

When the InitialContext class receives a URL string as a name argument to one of its methods, it looks for a URL context implementation. It does this by using the Context.URL_PKG_PREFIXES(in the API reference documentation) environment property. This property contains a colon-separated list of package prefixes. Each item in the list is a fully qualified package prefix of a URL context factory. The factory name is constructed using the following rule:
package_prefix . scheme . schemeURLContextFactory
The package prefix "com.sun.jndi.url" is always appended to the end of this list.

Typically, a service provider that supplies a context implementation will also supply a URL context implementation so that it can handle URL strings passed to the InitialContext. However, this is not a requirement and some service providers might not supply any URL context implementations. Suppose that the URL_PKG_PREFIXES property contains

com.widget:com.wiz.jndi
Also suppose that the following URL string is supplied to the lookup() method of the InitialContext class:
ldap://localhost:389/cn=homedir,cn=Jon%20Ruiz,ou=People,o=JNDITutorial
The JNDI will then look for the following classes:
com.widget.ldap.ldapURLContextFactory
com.wiz.jndi.ldap.ldapURLContextFactory
com.sun.jndi.url.ldap.ldapURLContextFactory
It next tries to instantiate each class in turn and invokes ObjectFactory.getObjectInstance(Object, Name, Context, Hashtable) (in the API reference documentation) until one of them produces a non-null answer. The answer, which is a context, is then used to carry out the originally intended method, using the URL string as the name argument.

Next, suppose that the JNDI successfully instantiated the com.wiz.jndi.ldap.ldapURLContextFactory class and obtains a context from it. The JNDI then invokes lookup() on the context and supply it "ldap://localhost:389/cn=homedir,cn=Jon%20Ruiz,ou=People,o=JNDITutorial" as the string name argument.

If the JNDI cannot find a URL context factory that returns a non-null answer, then the input URL string is passed to the underlying initial context implementation (i.e., that implementation specified in the Context.INITIAL_CONTEXT_FACTORY environment property).

See the Building a Service Provider (in the Building a Service Provider trail) trail for descriptions on how to write a URL context implementation.

Relationship to the Underlying Initial Context

You need to understand that no relationship exists between the implementation named by the Context.INITIAL_CONTEXT_FACTORY environment property and any URL context implementation other than all can be accessed via the same InitialContext instance. For example, suppose that you have the following environment property settings:
java.naming.factory.initial=com.wiz.jndi.ldap.LdapContextFactory
java.naming.factory.url.pkgs=
If you supply the name "ldap://localhost:389/o=JNDITutorial" to InitialContext.lookup(), then the list of URL context factory classes that the JNDI will try is
com.sun.jndi.url.ldap.ldapURLContextFactory
If the service provider came with a URL context factory, then the provider should supply an application resource file (jndi.properties) that contains the factory's package prefix. See the Environment Properties (in the Beyond the Basics trail) lesson for a description of application resource files. If the provider has a URL context factory but has not specified a package prefix for it in an application resource file, then you should specify it in your program or application resource file so that the JNDI can find the factory.

Relationship to Composite Names

To specify a URL string as part of a composite name to the methods in the InitialContext, make it the first component of a composite name. By doing this, you, in effect, use the URL string to name a context in which to continue operation on the rest of the name's components.

Here is an example that creates a CompositeName(in the API reference documentation) that consists of an LDAP URL string as the first component and filenames as the remaining components.

String url = 
    "ldap://localhost:389/cn=homedir,cn=Jon%20Ruiz,ou=people,o=JNDITutorial";

// Create a CompositeName in which the first component is a URL string
Name name = new CompositeName().add(url);

// Add the other components
name.add("tutorial").add("report.txt");

// Perform the lookup by using CompositeName
System.out.println(ctx.lookup(name));
You can't specify composite name components as part of the URL string itself because doing so might conflict with the URL's syntax.

More Than Just Names

Some URLs, such as those for the LDAP (RFC 2255), specify more than name components. The LDAP URL syntax allows you to specify the scope of the search and the search query, as well as the attributes to return. See the Miscellaneous (in the Tips for LDAP Users trail) lesson for more information and an example of how query components in a URL string are used.


Previous | Next | Trail Map | Beyond the Basics | URLs