Contexts provide a hierarchical structure to JNDI names, and composite names group together related names. The initial context provides a top-level view of the namespace and any sub-contexts reflect the hierarchical composite name structure.
The namespace represents contexts as names, and you can look these up just like any other name. You can obtain a listing of the names in a context by using Context.list(). This method provides a list of name and class bindings as a javax.naming.NamingEnumeration, where each element in the enumeration is a javax.naming.NameClassPair object. Listing 3.5 shows a simple program to list the names and classes for the example sams sub context.
You must run the JNDIBind program from Listing 3.1 before running this program; otherwise, the “sams” sub context will not exist. Running the program in Listing 3.5 will produce a single line of output:
java.lang.String – book
The parameter to the list() method defines the name of the context to list. If this is the empty string, the method lists the current context.
If the initial context of the J2EE RI namespace is listed, you must have the J2EE RI classes in your search path; otherwise, you will get an org.omg.CORBA.BAD_PARAM exception caused by another CORBA exception:
org.omg.CORBA.MARSHAL: Unable to read value from underlying bridge : Serializable readObject method failed internally minor code: 1398079699 completed: Maybe
Don't believe the completed: Maybe tagged on to the end of the error message. It didn't complete.
The easiest solution to this problem is to run the setenv script in the bin directory of J2EE RI. This script creates a variable CPATH that you can use as the CLASSPATH for running J2EE RI client programs.
Under Windows use
%J2EE_HOME%insetenv java –classpath .;%CPATH% JNDIList
Under Linux and Unix use
$J2EE_HOME/bin/setenv java –classpath .:$CPATH JNDIList
The CD-ROM accompanying this book includes the JNDIList program, which is the same as the program in Listing 3.5 but without the parameter to the list() method.
The list() method returns the name and the bound object's classname, but not the object itself. It is a lightweight interface designed for browsing the namespace.
A second method, called Context.listBindings(), retrieves the object itself. The listBindings() method returns a NamingEnumeration, where each element is of type javax.naming.Binding. Access methods in the Binding class support retrieval of the information of the bound object. Listing 3.6 shows a simple recursive tree-walking program that is a useful diagnostic tool for examining JNDI namespaces.
Binding a composite name will automatically create any intermediate sub-contexts required to bind the name. Binding the name com/sams/publishing/book/j2ee in 21 days creates the following sub-contexts if they don't already exist:
com com/sams com/sams/publishing com/sams/publishing/book
You can explicitly create contexts with the Context.createSubcontext() method. The single method parameter is the name of the context. If this is a composite name, all intermediate contexts must already exist. The createSubContext() method will throw a NameAlreadyBoundException if the name already exists.
Note
Contrary to the API documentation, the J2EE RI naming service will automatically create any intermediate contexts.
Listing 3.7 shows a simple program for creating arbitrary contexts.
The Context.destroySubcontext() method can destroy contexts. Again, the single method parameter is the name of the context. The context does not have to be empty, because the method will remove from the namespace any bound names and sub-contexts with the destroyed context.
Listing 3.8 shows a simple program for deleting arbitrary contexts.
Use this program with caution, because destroying the wrong context will render your J2EE server unusable. If you are using the J2EE RI, restarting the J2EE server can rectify a mistake; this might not be the case with other servers.
The destroyContext() method can throw a NameNotFoundException if the name doesn't exist and a NotContextException if the bound name is not a context.
3.138.69.163