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
<naming>
<context>
<environment name="..." value="..." type="..." />
...
<resource name="..." type="...">
<parameter>
<name>...</name>
<value>...</value>
</parameter>
...
</resource>
</context>
</naming>
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:
<naming>
<context>
<resource name="jdbc/pool" type="javax.sql.DataSource">
<parameter>
<name>driverClassName</name>
<value>org.hsqldb.jdbcDriver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:hsqldb:target/hsqldb</value>
</parameter>
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
</resource>
</context>
</naming>
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:
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"));
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");
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,
<naming>
<context name="myApp/config">
... same as above ...
</context>
</naming>
Context ctx = new InitialContext();
Context env = (Context) ctx.lookup("myApp/config");
DataSource ds = (DataSource) env.lookup("jdbc/pool");
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.