4 Replies Latest reply on Apr 25, 2013 10:16 PM by beubanks

    JNDI datasource lookup not working from Quartz thread.

    beubanks

      I have an application that uses JNDI to lookup a datasource configured in my JBoss AS 7.1.3 server. It uses the datasource for running a report. When I run the report directly through the web interface (and thus in the thread that handles the HTTP requests), the JNDI lookup works fine. However, when the same report is run from a Quartz job, it throws the following error.

       

      javax.naming.NameNotFoundException: java:comp/env/jdbc/example

          at org.jboss.as.naming.InitialContext.lookup(InitialContext.java:127)

          at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:215)

          at javax.naming.InitialContext.lookup(InitialContext.java:411)

          ...

       

      The code that does the lookup in the Quartz job is the same code that does the lookup for the manually-run report. (Based on the stack trace, although I don't have the original source.)

       

      To compare the behavior, I forced it to fail for the manual run by changing the JNDI name to an invalid name, and I got the following:

       

      javax.naming.NameNotFoundException: env/jdbc/invalidname -- service jboss.naming.context.java.module.examplewar.examplewar.env.jdbc.invalidname
          at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:97)
          at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:179)
          at org.jboss.as.naming.InitialContext.lookup(InitialContext.java:129)
          at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:215)
          at javax.naming.InitialContext.lookup(InitialContext.java:411)
          ...
      

       

      Notice the lack of "java:comp/" in the manually executed example. That's weird, because I decompiled the code using JD-GUI, and the line that calls InitialContext.lookup() explicitly prepends "java:comp/env/" like this:

       

      DataSource ds = (DataSource)this.ctx.lookup("java:comp/env/" + jndiName);
      

       

      So it looks to me like it's seeing the JNDI context differently in Quartz thread. Any ideas why it would do that, or what's really happening?

       

      Datasource in standalone.xml:

        <datasource jta="true" jndi-name="java:/jdbc/example" pool-name="exampleDS" enabled="true" use-java-context="true" use-ccm="true">
          ...
        </datasource>
      

       

      Datasouce configuration in web.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app version="2.4"
          xmlns="http://java.sun.com/xml/ns/j2ee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
      
          ...
          
          <resource-ref>
            <description>Example Database</description>
            <res-ref-name>jdbc/example</res-ref-name>
            <res-type>javax.sql.DataSource</res-type>
            <res-auth>Container</res-auth>
            <lookup-name>java:/jdbc/example</lookup-name>
            <res-sharing-scope>Shareable</res-sharing-scope>
          </resource-ref>
          
          ...
          
      </web-app>
      

       

      jboss-web.xml:

      <?xml version="1.0" encoding="UTF-8" ?>
      <jboss-web>
        <resource-ref>
          <description>Example Database</description>
          <res-ref-name>jdbc/example</res-ref-name>
          <res-type>javax.sql.DataSource</res-type>
          <res-auth>Container</res-auth>
          <lookup-name>java:/jdbc/example</lookup-name>
          <res-sharing-scope>Shareable</res-sharing-scope>
        </resource-ref>
      </jboss-web>
      

       

      Thanks,

      Bron

        • 1. Re: JNDI datasource lookup not working from Quartz thread.
          sfcoy

          The "java:comp/env/" namespace is only available to the component in which it is declared from threads that are managed by the application server. This is because there's transactional and security contexts associated with the thread which get propogated to the resource in question.

           

          Quartz threads are unmanaged.

           

          I'd just replace the quartz timer with an EJB timer - which can be added directly into your webapp.

           

          BTW. Quartz has the same problem on every application server, not just JBoss.

          • 2. Re: JNDI datasource lookup not working from Quartz thread.
            beubanks

            Thanks for explaining that Stephen. Unfortunately, the change would be a bit involved, and I don't have the original code. I could get the code if I wanted to, but it's not worth the effort. I've got a workaround that I really wanted to avoid, but it looks like that's my only choice.

            • 3. Re: JNDI datasource lookup not working from Quartz thread.
              jaikiran

              Or you could just change that lookup code to use java:/jdbc/example JNDI name instead of the java:comp namespace one.


              • 4. Re: JNDI datasource lookup not working from Quartz thread.
                beubanks

                jaikiran pai wrote:

                 

                Or you could just change that lookup code to use java:/jdbc/example JNDI name instead of the java:comp namespace one.


                 

                No, it's hard coded, and I can't change the code (at least not without more time than I've got available). If I could've changed the code, I would have done that a long time ago.