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.