The Context and InitialContext Objects

   

The Context and InitialContext Objects

We have mentioned the term binding several times in this chapter. Although there is a Binding class in the JNDI API, you deal most often with something called a Context . A Context plays a central role in JNDI. It is used to bind, unbind, and locate objects that have been associated with a name in JNDI. The Context is represented by the javax.naming.Context interface. This interface has the necessary methods to put objects into the naming service and also to locate them. Table 4.2 lists the most commonly used methods from the Context interface when dealing with EJB.

Table 4.2. Most Often Used Methods in the Context Interface for EJB

Return Type

Method

Description

Object

lookup(String name)

Returns the object associated with the name.

NamingEnumeration

listBindings(String name)

Returns a list of bindings that are under the context at this name.

Hashtable

getEnvironment()

Retrieves the environment for this context.

void

close()

Closes the context.

Many other methods are defined in the Context interface, but the ones in Table 4.2 are the ones that you will be using the most with EJB.

All naming services have a root entry point. Think of this as the beginning of the namespace. All clients need to start from somewhere in the namespace and this starting point is called an InitialContext . Typically, the first step for any client that wants to use a naming service is to create an instance of the InitialContext . The javax.naming.InitialContext class represents the starting point for a client using a JNDI naming service. The InitialContext class implements the Context interface; it has all the methods in Table 4.2 and more at its disposal.

To create an InitialContext , you just need to call the constructor for it. The InitialContext must be able to find the environment properties that we discussed earlier. The particular environment properties that are required depend on the naming service SPI that you are using. For our file system example, we need to specify the following two properties:

  • java.naming.factory.initial

  • java.naming.provider.url

In fact, these two properties are typically always needed by the InitialContext to find and acquire a connection to the naming service.

There are really just three steps in obtaining an InitialContext .

  1. Select the service provider of the corresponding service you want to access.

  2. Specify any configuration that the InitialContext needs.

  3. Call the InitialContext constructor, either by supplying the environment properties or by allowing them to be found either by a resource file or the system properties.

Caution

A single instance of an InitialContext is not guaranteed to be thread-safe. If you have multiple threads that need to access the instance of the InitialContext , they should synchronize themselves or use separate instances of the InitialContext . You can pass null into the lookup method and get back a new reference to the same Context , which may have its environment modified without affecting the original Context . You can also access this new Context concurrently with the original.


Listing 4.2 shows an example of creating an InitialContext to our file system naming service.

There are two environment properties that we must specify when using the file system as a JNDI naming service. The first one is to tell which initial context factory we will be using. For the file system, the value of this property is

 Context.INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory 

The second environment property is the provider URL. In the case of the file system, this will be the directory that we want to be the root context. As mentioned previously in this chapter, the format of this value is dependent on the service provider that's being used. For the file system, it should look like this:

 Context.PROVIDER_URL=file:///c:/jndi_root/ 

This file system service provider requires the prefix file:/// to be added to the root directory.

For this example, we are going to pass the environment properties into the constructor of the InitialContext . The provider URL for this example comes from the command line because everyone might be using a different directory for the root context. As we said earlier, there are times when putting everything into the jndi.properties isn't the best approach.

Listing 4.2 An Example of Obtaining an InitialContext
 import javax.naming.*;  import java.util.Hashtable;  import java.util.Properties;  public class JNDIClient {   // Default Constructor    public JNDIClient(){     super();    }    // Create an InitialContext using the environment properties passed in    public Context getInitialContext( Hashtable env ) throws NamingException{     // Create the InitialContext using a Hashtable of properties      return new InitialContext( env );    }    public static void main( String[] args ){     // Reference for the InitialContext      Context initCtx = null;      // Ensure that the providerURL is passed in on the command line      if ( args.length == 0 ){       System.out.println( "Usage: JNDIClient <providerURL>" );        System.exit( 0 );      }      // Create an instance of the JNDIClient      JNDIClient client = new JNDIClient();      // Create the environment variables for the InitialContext      Hashtable env = new Hashtable();      env.put( Context.INITIAL_CONTEXT_FACTORY,                "com.sun.jndi.fscontext.RefFSContextFactory" );      env.put( Context.PROVIDER_URL, args[0] );      try{       // try to get the InitialContext        initCtx = client.getInitialContext( env );        if ( initCtx != null ) {         System.out.println ("InitialContext was created successfully");        }else{         System.out.println ("InitialContext was not created successfully");        }      }catch( NoInitialContextException ex ){       ex.printStackTrace();      }catch( NamingException ex ){       ex.printStackTrace();      }finally{       try{         System.out.println( "Closing the InitialContext" );          // Only call close on a non-null InitialContext reference          if ( initCtx != null )            initCtx.close();        }catch( Exception ex ){         System.out.println( "Could not close the InitialContext" );        }      }    }  } 

It's probably a good idea to walk through the example in Listing 4.2 and figure out what's really going on. The JNDIClient program takes a single argument, which is the providerURL . This argument will be passed into the environment properties. We could have also set the value in the jndi.properties resource file, but this way is easier for you to change and see what different results are obtained based on different values. For the file system SPI, this value represents the root directory.

After a Hashtable is created with the correct values, the getInitialContext method is called and the environment properties are passed in. Remember, we could have also specified the values in a resource file or the system properties. We did it this way to provide a little more insight and to make it easier to change the providerURL value on the command line. You'll see an example later in this chapter on using a resource file.

After the InitialContext object is created, the program immediately closes it because for this example, we are only trying to show how to create one.

Assuming you are using the directory c:\jndi_root , if you run the preceding program from the command line and pass in the root directory like this:

 java JNDIClient file:///c:/jndi_root/ 

you should see the following output:

 C:\>java JNDIClient file:c:///jndi_root  InitialContext was created successfully  Closing the InitialContext  C:\> 
graphics/01icon01.gif

Be sure that you have fscontext.jar and providerutil.jar in your system classpath to run the examples. If you still are having trouble running the JNDIClient example, check the " Troubleshooting " section at the end of this chapter for help.

Closing an InitialContext

You should always close the InitialContext object when you are finished with it. This is similar to closing any other finite resource such as a JDBC connection. You should also ensure that you close the InitialContext even when an exception is thrown. The best way to do this is by putting the close method in a finally block. You also should put a try/catch around the close method. Listing 4.3 illustrates how you can ensure that the InitialContext is always closed when your application is finished with it.

Listing 4.3 The Proper Method for Closing an InitialContext
 try{   // some jndi work being performed  }catch( Exception ex ){   // handle the exception  }finally{   try{     if ( initCtx != null )        initCtx.close();    }catch( Exception ex ){     System.out.println( "Could not close the InitialContext" );    }  } 


Special Edition Using Enterprise JavaBeans 2.0
Special Edition Using Enterprise JavaBeans 2.0
ISBN: 0789725673
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net