Initial Context Naming Exceptions

The runtime system reports errors in using JNDI as a subclass of NamingException. The exceptions most likely to occur for accessing the initial context are as follows:

javax.naming.CommunicationException: Can't find SerialContextProvider

This exception usually means the JNDI Server is not running, or possibly the JNDI properties for the server are incorrect (see the next section, “Defining the JNDI Service”).

javax.naming.NoInitialContextException: Need to specify class name in environment or
 system property, or as an applet parameter, or in an application resource file: java
.naming.factory.initial

This exception occurs when the IntialContext class does not have default properties for the JNDI Service Provider, and the JNDI server properties have not be configured explicitly (see the next section, “Defining the JNDI Service”).

javax.naming.NoInitialContextException: Cannot instantiate class: XXX
 [Root exception is java.lang.ClassNotFoundException: XXX]

This exception occurs when the class path defined for the JNDI program does not include the JNDI server classes (see the next section, “Defining the JNDI Service”).

javax.naming.ServiceUnavailableException: Connection refused: no further information
[Root exception is java.net.ConnectException: Connection refused: no further information]

This exception occurs when the JNDI properties for the program fail to match the JNDI Service Provider currently in use (see the next section, “Defining the JNDI Service”).

Defining the JNDI Service

During program development, it is reasonable to use a JNDI service running on the local machine that uses the default service provider supplied with the J2EE server. When you deploy the program, you must make use of the enterprise-wide naming service for your site. You will need to configure the program to use a specific naming server and not the default one provided with your test J2EE server.

The parameters that you usually need to define for the JNDI service are as follows:

  • JNDI service classname

  • Server's DNS host name

  • Socket port number

A particular server vendor's implementation may require additional parameters.

There are several ways of defining the JNDI service properties for a program, but you only need to use one of them. You can either

  • Add the properties to the JNDI properties file in the Java runtime home directory

  • Provide an application resource file for the program

  • Specify command-line parameters to be passed to an application

  • Specify parameters to be passed into an applet

  • Hard-code the parameters into the program

The last option is the weakest approach, because it restricts the program to working with one type of JNDI service provider on one specific host.

The first two options are the most suited to production environments. They both require that you distribute simple text configuration files with the program.

JNDI Properties Files

An application resource file called jndi.properties defines the JNDI service. The JNDI system automatically reads the application resource files from all components in the program's CLASSPATH and from lib/jndi.properties in the Java runtime home directory (this is the jre sub-directory of the Java JDK home directory).

The following example from Sun Microsystems' J2EE RI shows a typical jndi.properties file:

java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=com.sun.enterprise.naming

Each entry in the property file defines a name value pair. The InitialContext object uses these properties to determine the JNDI service provider.

The J2EE server vendor usually supplies a sample jndi.properties file defining the properties that need to be configured with their server. You can find the J2EE RI jndi.properties file in the lib/classes directory in the J2EE RI installation directory.

Normally, any given JNDI service will require the following named properties:

java.naming.provider.url

This defines the DNS host name of the machine running the JNDI service and the service port number. This is the only property that the network administrator needs to customize. The property value is a machine name with an optional colon and port number. By default, JNDI uses port 1099, and most sites do not change this value. The default server is usually localhost.

Consider a host called nameserver in the Sams Publishing domain (samspublishing.com), the full URL including port number for a default JNDI server on this host would be as follows:

nameserver.samspublishing.com:1099

java.naming.factory.initial

You set this property to the classname (including the package) of the Initial Context Factory for the JNDI Service Provider. This value effectively determines which JNDI Service Provider you use. To use the default Naming Service supplied with the J2EE RI, you would specify this property as follows:

java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory

java.naming.factory.url.pkgs

This property defines prefix package names the InitialContext class uses for finding other classes JNDI requires. The J2EE RI uses the following value for this property:

java.naming.factory.url.pkgs=com.sun.enterprise.naming

More information on these and other JNDI properties can be found in the API documentation for the Context class and in the JNDI Tutorial from Sun Microsystems.

The simplest way to define the JNDI Service Provider is to configure every client's Java home directory to include the necessary JNDI properties. This approach suits an intranet where all machines are centrally managed.

Another approach is to include a suitable JNDI properties file with the client program and distribute everything as a JAR file (program class files and the jndi.properties file). This suits Web-based intranets or extranets, where applets are used or where you can distribute the client JAR file to users.

Application Properties

Using the -D option, you can supply the JNDI properties on the java command line of an application. This has the disadvantage of requiring long command lines that are hard to remember and easy to mistype. A way around this problem is for you to provide script files to run the application on the target platforms; typically, you will supply batch files for Windows and shell scripts for Linux and Unix.

The following is an example of a command line that defines the JNDI factory classes and server:

java -D
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory –D java
.naming.provider.url=localhost:1099 MyClass

Providing a jndi.properties file in the application JAR file is a cleaner solution than providing command-line parameters. However, using command-line parameters makes the JNDI properties more apparent when customizing the application for a local site. It is easy to overlook a jndi.properties file in a JAR file.

Applet Parameters

An applet can accept the JNDI properties as parameters, for example

<applet code="MyApplet.class" width="640" height="480">
<param name="java.naming.factory.initial"
    value= "com.sun.enterprise.naming.SerialInitContextFactory" >
<param name="java.naming.provider.url"
    "value= localhost:1099">
</applet>

Using parameters with the applet HTML file makes the JNDI properties more apparent when customizing the applet for a local site. A jndi.properties file in the jar file is easily overlooked.

Hard-Coded Properties

The least desirable way to specify the JNDI properties is via hard-coded values in the program. Hard coding the properties means including the JNDI classnames and the server name in the source code. This is undesirable because it means that should the network architecture change, you must edit, recompile, and redistribute the program. Obviously, you want to avoid this maintenance overhead if you can. The network architecture may change if the JNDI service moves to a different server or you install a new JNDI Service Provider.

The mechanism for defining the service in code is via a hash table of properties passed into the InitialContext constructor:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
    "com.sun.enterprise.naming.SerialInitContextFactory");
env.put(Context. PROVIDER_URL,
    "localhost:1099");
Context ctx = new InitialContext(env);

Notice how the code uses symbolic constants from the Context class rather than using strings representing the properties (such as "java.naming.factory.initial"). This approach makes the code more portable should the property names change in future versions of Java or JNDI.

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

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