Configuring JNDI resources using XMLConfigurator

The XMLConfigurator allows you set JNDI environment entries and to configure and load JNDI resources using xml configuration files. The xml syntax is similar to that used by Jakarta Tomcat's server.xml and the J2EE web.xml configuration files. For a full introduction to JNDI resources and resource factories, see Tomcat JNDI Resources HOW-TO

The structure of the configuation file is

       

The environment entries achieve the same effect as env-entry elements in web.xml. The resource elements behave like Resource elements in server.xml. Note that here "resource" starts with a lower case "r" and the parameter elements are its content (In Tomcat's server.xml, Resource is an empty tag and the parameters are included in a ResourceParams element.)

Here is an example, showing how to configure a database connection pool and then get a connection from the pool in your application.

Start by setting up a JNDI environment including a datasource in an xml configuration file, like so:

       

The JNDI resource being configured above is a database connection pool. Naming provides a default resource factory for database connection pools using Jakarta Commons DBCP. This is the factory that will be used to create the pool. In order for this factory to work, you need to have Jakarta Commons DBCP (version 1.0) and Jakarta Commons Pool (version 1.0.1) in your classpath.

The parameters that follow specify the database driver, url, username and password.

To use a connection from the pool at run time, you need to do three things:

  1. Initialize JNDI using the xml configuration file above. Assuming the xml file is stored in "/example-jndi.xml", you can do this in one line:

    XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/example-jndi.xml"));
                 

  2. Perform a JNDI lookup to get a DataSource reference:

    Context ctx = new InitialContext();
    Context env = (Context) ctx.lookup("java:comp/env");
    DataSource ds = (DataSource) env.lookup("jdbc/pool");
                 

  3. Use the reference to access the database:

    Connection con = null;
    try {
        con = ds.getConnection();
           // use con to access db
        ...
        } finally {
           // cleanup database access objects
           ...
           if (con != null) { 
           con.close(); 
        }
    }
                 

As in the example above, by default the root of the namespace created by the XmlConfigurator is "java:comp/env". This may be overridden by supplying a name attribute in the top-level context element. For example,

     
would allow you to use
Context ctx = new InitialContext();
Context env = (Context) ctx.lookup("myApp/config");
DataSource ds = (DataSource) env.lookup("jdbc/pool");
     

Using the Naming APIs directly to set up JNDI

To set up and use a JNDI naming context using the JNDI APIs directly, you need to set some JNDI environment properties, create an initial context and then use the standard JNDI APIs to set up bindings and perform lookups.

You can use a jndi.properties properties file to set the environment properties for the initial context, or you can do it as follows in your code:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
    "org.apache.naming.java.javaURLContextFactory");
env.put(Context.URL_PKG_PREFIXES,"org.apache.naming");
        

Then create the initial context:

Context initialContext = new InitialContext(env);
       

Once created, you can add bindings to the context using the javax.naming.Context API:

compContext = initialContext.createSubcontext("java:comp");
envContext =  compContext.createSubcontext("env");
envContext.bind("host", "www.apache.org");
envContext.bind("port", new Integer(80)); 
       

Now initialContext.lookup("java:comp/env/host")) will return a String holding the value "www.apache.org" and initialContext.lookup("java:comp/env/port")) will return an Integer with intValue equal to 80.