It's been quite a ride porting our EAR from JBoss 4.2.1 to WebSphere 6.1. Installation issues on CentOS and Precompiling JSPs were just a few of the issues we encountered. We are still producing 2 different EARs, but both are based on identical WARs.
The latest issue had to do with receiving a WebSphere exception from a Init Servlet that started a separate Thread. This Thread contained code that indirectly performed a JNDI lookup to get a Datasource. Unlike JBoss, WebSphere apparently doesn't like Unmanaged Threads performing JNDI lookups.
Here is the WebSphere exception:
"javaURLContex E NMSV0310E: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component. This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request. Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on "java:" names"
This seems to be a rather common issue in WebSphere with multiple possible solutions. I guess ideally you should try and configure a container-managed Thread using CommonJ (see section Scheduling and thread pooling). Unfortunately, the configuration is different for JBoss.
Fortunately, I think I stumbled upon another solution. While reviewing the WAR Spring applicationContext.xml file that configured our Datasource I noticed a property called lookupOnStartup. It was set to false and when setting it to true, the exception went away.
When setting it back to false the exception appeared again; setting it back to true the exception was gone. Unfortunately, I can only speculate as to why this solved the issue. My guess is, when lookupOnStartup was false, the first attempt to get the Datasource was from a separate Thread which WebSphere didn't like. However, when setting lookupOnStartup to true, the first time the Datasource was retrieved was by a container-managed Thread and once my separate Thread needed the Datasource it was already looked up and cached. According to the javadocs for JndiObjectFactoryBean.setLookupOnStartup the default is true, so it can't be that bad, right? I can't think of a reason why someone would want this delayed.
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/MY-DS"/> <property name="lookupOnStartup" value="true"/> <property name="cache" value="true"/> <property name="proxyInterface" value="javax.sql.DataSource"/> </bean>
If you ever run into this issue, you might consider setting lookupOnStartup to true and see if that fixes your issue.