Friday, October 1, 2004

Locate your JDBC DataSource in WebSphere Application Server using JNDI

"The WebSphere Application Server initial context factory, com.ibm.Websphere.naming.WsnInitialContextFactory, is typically used by WebSphere Application Server applications to perform JNDI operations. The WebSphere Application Server run-time environment is set up to use this WebSphere Application Server initial context factory if one is not specified explicitly by the JNDI client."

Based on that information, and my own experience that you can leave the WebSphere-specific initial context factory parameter out and still obtain correct results, I'd say that explicitly naming the initial context factory is redundant. It doesn't hurt anything to throw that in, though, and that is the recommended procedure.

However, that is not the source of the problem in locating your DataSource. The problem is in the way that you specify the DataSource name.

The Easy Fix

The simplest way to correct this problem is just to strip out all of the prefix information and refer to your DataSource directly by the JNDI name (jdbc/myDataSource):

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.ibm.Websphere.naming.WsnInitialContextFactory");
InitialContext ctx = new InitialContext(env);
DataSource ds = (DataSource) ctx.lookup("jdbc/myDataSource");

WebSphere supports such direct JNDI references to JDBC DataSources, but this does result in a rather annoying little problem. If you look into your server log, you will now see a number of logged messages that look something like this:

I J2CA0122I: Resource reference jdbc/myDataSource could not be located, so default values of the following are used: [Resource-ref settings]

        res-auth:                 1 (APPLICATION)
        res-isolation-level:      0 (TRANSACTION_NONE)
        res-sharing-scope:        true (SHAREABLE)
        res-resolution-control:   999 (undefined)

I J2CA0107I: Component-managed authentication alias not specified for connection factory or DataSource myDataSource.

Now, these messages are completely harmless, and will not prevent your application from functioning correctly; however, if you want to get rid of them, you'll have to go to the extra trouble of performing the look-up using the recommended procedure.

The Preferred Method

The method recommended by IBM is to use a resource alias to locate your JDBC DataSource rather than specifying the JNDI name directly. This actually looks a little closer to the old, familiar method, although you don't see the jdbc portion of the name:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.ibm.Websphere.naming.WsnInitialContextFactory");
InitialContext ctx = new InitialContext(env);
DataSource ds = (DataSource) ctx.lookup("java:comp/env/myDsAliasName");

The only problem with this method is that in order to refer to your DataSource by an alias name, you have to define the alias. You do that when you set up your Web application, and the easiest way to perform this task is through WebSphere Studio Application Developer.

If you open your Web application project in WebSphere Studio Application Developer, you can bring up the Deployment Descriptor in edit mode by double clicking on the Deployment Descriptor entry in the project tree. Using the tabs at the bottom of the Deployment Descriptor edit pane, navigate to the References panel.