views:

205

answers:

3

I have a J2EE webapp which is used to upload a file which is then processed by a database procedure. Because we do not want the webapp to have to wait until the database procedure completes, it is executed in a different thread.

The process running in the separate thread needs to obtain and close its own connection. The webapps usually look up the datasource jndi name using a ServiceLocator which in turn looks it up from the application context (the lookup key for the jndi name is defined as a class constant) but for the separate thread looking up the jndi name with the ServiceLocator fails. To get around this problem we have used the jndi name as the class constant instead, so that the thread can look up the datasource directly.

This means that the jndi name for the datasource is now fixed for the application, and we can no longer deploy the same application in the same container but with different datasources simply by modifying the web.xml.

What are industry best practices around this? Should the jndi name be configurable or is it OK to fix it for the application? Has anyone implemented a configurable datasource jndi name solution that is usable both in the webapp and by other threads in the container?

+1  A: 

You could pass the JNDI name or the DataSource in as constructor or method argument of the thread class.

BalusC
+1  A: 

Yeah - I feel your pain.

I do think it is a very good idea to try and make the jndi configurable via the web.xml. The way I've handled this is cached the datasource reference. iow, on startup of the webapp the datasource referenced is sourced while it is available to the thread and then passed to or made available to any other object which requires it.

Michael Wiles
+2  A: 

For best practices, The role of JNDI in J2EE (co-authored by Kirk Pepperdine) is one of the best article I've found. It explains clearly the "vision" of Sun regarding development, packaging, deployment and how JNDI fits in there.

The short version is that Sun and application servers providers provide a way to define and name a global resource (java:DefaultDS) and to bind the local resource ref name (jdbc/mydatasource) to the named resource.

This solves the portability issue of an application (made of J2EE components). But the local resource ref name is component-specific so it doesn't solve your issue (which is deploying the same component several times, but with different local resource ref name).

In other words, Sun's vision doesn't address your particular use case (although I think it's a valid use case). With Sun model, you should solve this at build/packaging time (i.e. create and assemble two versions of the component, each using a specific local resource ref name).

The programmatic approach you describe (performing a lookup of the value from a key stored in JDNI/properties/whatever) is a workaround.

Pascal Thivent