Jetty, JNDI, and data sources

I have a need to access some arbitrary databases defined using JNDI from within my Grails application. These are databases in addition to the one defined for the environment in DataSource.groovy.

I define them in my server configuration (context.xml for tomcat) and look them up from the Grails application myself. This works great using tomcat. When I try to define multiple data sources within Jetty (so that IntelliJ and grails run-app, etc. will work with them) they do not seem to be there, although my defined Grails environment JNDI data source is there – no problem.

The exception ends up looking like this. (This is on new InitialContext().lookup("java:comp/env/jdbc/AnotherDB").)

javax.naming.NameNotFoundException; remaining name ‘AnotherDB’
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:578)
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:665)
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:665)
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:665)
    at org.mortbay.naming.NamingContext.lookup(NamingContext.java:680)
    at org.mortbay.naming.java.javaRootURLContext.lookup(javaRootURLContext.java:112)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
[snip]

My jetty-env.xml looks like:

[snip]
    <New id=”GrailsDB” class=”org.mortbay.jetty.plus.naming.Resource”>
      <Arg>jdbc/GrailsDB</Arg>
      <Arg>
        <New class=”org.apache.commons.dbcp.BasicDataSource”>
           <Set name=”driverClassName”>com.ibm.db2.jcc.DB2Driver</Set>
           <Set name=”url”>jdbc:db2://dbserver:1/grailsdb</Set>
           <Set name=”username”>me</Set>
           <Set name=”password”>mypwd</Set>
        </New>
      </Arg>
    </New>
    <New id=”AnotherDB” class=”org.mortbay.jetty.plus.naming.Resource”>
      <Arg>jdbc/AnotherDB</Arg>
      <Arg>
        <New class=”org.apache.commons.dbcp.BasicDataSource”>
           <Set name=”driverClassName”>com.ibm.db2.jcc.DB2Driver</Set>
           <Set name=”url”>jdbc:db2://dbserver:3/anotherdb</Set>
           <Set name=”username”>me</Set>
           <Set name=”password”>mypwd</Set>
        </New>
      </Arg>
    </New>[snip]

GrailsDB is available without a problem.

The trick is to realize/remember that Jetty insists on having a resource-ref in the web.xml file; without it the data source never gets bound to the context (I think) with Jetty. So to get my lookup to start finding the AnotherDB data source I make sure I have this in my web.xml file.

  <resource-ref>
    <description>Another database connection</description>
    <res-ref-name>jdbc/AnotherDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

In case you have not done so already, you can get the Grails web.xml file placed under the src/templates/war directory of your project by running the grails install-templates command so that you can modify it as needed.

Leave a comment