Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Tomcat inject the JNDI component-local context?

Tags:

java

tomcat

jndi

In Tomcat, you can specify resources (JDBC connection, Javax mail sessions, etc.) in context.xml, reference them in web.xml, and then load them in Java like so:

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

I'm interested in what magical voo doo is going on here! I would have expected the need to inject the InitialContext constructor with a hashtable or some other object, thereby injecting it with everything defined in context.xml and web.xml. But it's a no-arg constructor!!!

So I ask: what does Tomcat do to fill in the "missing link" between the 2 XML files and the InitialContext no-arg constructor so that the DataSource is magically available from the ctx instance? Thanks in advance!

like image 322
IAmYourFaja Avatar asked Jul 10 '13 14:07

IAmYourFaja


3 Answers

There are several parts to the magic voodoo as you describe it.

First of all early in the startup process Tomcat calls:

System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
        "org.apache.naming.java.javaURLContextFactory");

This tells the JVM to use Tomcat's own factory for creating instances of InitialContext.

The second part is based around the fact that each web application has its own class loader and that all user code executes with that class loader set as the thread context class loader. Therefore, when a new InitialContext is created, Tomcat can look at the thread context class loader to determine which web application is making the request.

From there it is a simple process to hook up the new InitialContext object wth the right set of JNDI resources for the current application.

like image 160
Mark Thomas Avatar answered Nov 11 '22 20:11

Mark Thomas


At startup tomcat reads context.xml and creates all the resources defined there, and registers them with it's JNDI context. The code the you have posted is just the way to get those resources.

In web.xml (which is read when the web app is being deployed), the resources defined are not brand new. These are local to the web application, but will point to the resources defined in context.xml. The purpose of this is so that the Java code in your web app would be looking up the server resources indirectly.

like image 29
Bhesh Gurung Avatar answered Nov 11 '22 22:11

Bhesh Gurung


According to the Tomcat documentation:

The InitialContext is configured as a web application is initially deployed, and is made available to web application components (for read-only access).

If I had to guess, they just read the static location of your config files($CATALINA_BASE/conf/server.xml etc) and provide it for each web application as they're deployed. The documentation also covers in detail each type of entry for each file and how each are treated.

Looking at the source code for IntialContext.java your hunch about a HashTable is correct, it does have a constructor for one and appears to store entries in a HashTable, myProps.

like image 40
Durandal Avatar answered Nov 11 '22 22:11

Durandal