Root exception is javax.naming.NameNotFoundException: Name jdbc not found in context "java:comp/env"

5.8k views Asked by At

I am working on a Java Web Application, and is getting deployed in Websphere Application Server,

I have a class Database.java, which is returning the JDBC Connection with DB2 Database,

        jndiName = "jdbc/TestDataSource";
        Context ctx = new InitialContext();
        envContext = (Context) ctx.lookup("java:comp/env");
        javax.sql.DataSource ds = (javax.sql.DataSource) envContext.lookup(jndiName);
        conn = ds.getConnection();

and in other classes where am performing operations am creating an object of Database.java class and get the connection and did the jdbc operations, so far it was working fine, but in latest development I have to introduce a thread in servlet class, so the other classes which are doing the operations are running in thread in background and returned the control to servlet immediately. But after implementing this application crashed in Websphere Application Server with below mentioned error, but surprisingly its working perfectly fine Tomcat server.

PFB the Web.xml

<resource-ref>
        <description>Connection-ConnectionPool</description>
        <res-ref-name>jdbc/TestDataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
        <mapped-name>jdbc/TestDataSource</mapped-name>
</resource-ref>

Error: 000000e9 SystemOut O Error in NamingException - Database.getConnection(datasource) :- javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operations 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. [Root exception is javax.naming.NameNotFoundException: Name jdbc not found in context "java:comp/env".]

1

There are 1 answers

0
njr On

The exception means that the thread which you created doesn't have the context of the Java EE application and thus it cannot know which Java EE component namespace to get java:comp/env/jdbc/TestDataSource from. Note that you can define this same name to mean different things for different Java EE apps/components. There is an easy way around this, which follows Java EE spec standards. Instead of creating your own threads, use a ManagedExecutorService (also part of Java EE) that automatically propagates your application's context to a managed thread, in which case the app server will be able to resolve the lookup properly.

Here is an example:

ExecutorService executor = InitialContext.doLookup("java:comp/DefaultManagedExecutorService");

executor.submit(new Callable<Object>() {
    public Object call() throws Exception {
        DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/TestDataSource");
        Connection conn = ds.getConnection();
        try {
           // ... do useful stuff with connection
        } finally {
           conn.close();
        }
        return result;
    }
});