24
2008
Grails, Jetty, Glassfish and JNDI Data Sources
Today I’ve moved a bunch of my Grails apps over to JNDI Data Sources, and while it’s fresh in my mind, I thought I’d document a few of the tips and tricks involved.
First of all, why would you even want to use JNDI data sources? A few good reasons:
- Most importantly, your app server can probably manage your database connections a lot better than you can
- You don’t have to embed your username/password data in config files, and then end up committing them to public repos (this has led to several password changes for me in the past… the shame!)
- Developers can call their local databases whatever they want (and they can be whatever type of database server they like) – just map the JNDI reference to whichever server and database floats your boat.
- Does away with the need to ship db-specific drivers with your app (well.. in theory.. if you’re using Jetty for your DEV work , this may well not be true)
So what changes have I had to make? Just a few tiny ones to DataSource.groovy. Here’s the new one for groovyblogs:
dataSource {
pooled = false // JNDI, baby. All the way...
}
// environment specific settings
environments {
development {
dataSource {
// check out /web-app/WEB-INF/jetty-env.xml for the details
dbCreate = "update"
jndiName = "java:comp/env/jdbc/groovyblogs"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDb"
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
}
}
production {
dataSource {
dbCreate = "update"
jndiName = "jdbc/groovyblogs"
}
}
}
First of all, I need to turn pooling off, since the container will now handle all of that for me. But how come the settings are different for DEV and PROD? The answer lies in how containers handle JNDI referencing.
In the DEV example above, I’m running Jetty to do all of my local PC dev work (ie. the standard container that ships with Grails). Embedded Jetty needs to have JNDI references specified using ENC naming (java:comp/env/jdbc/blah), which is resolves against a container specific file to find out the “real” underlying database settings. Enter our friend /web-app/WEB-INF/jetty-env.xml. For groovyblogs, that looks something like:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<New id="domainDb" class="org.mortbay.jetty.plus.naming.Resource">
<Arg>jdbc/groovyblogs</Arg>
<Arg>
<New class="org.postgresql.ds.PGSimpleDataSource">
<Set name="user">username</Set>
<Set name="password">password</Set>
<Set name="databaseName">groovyblogs</Set></New>
</Arg>
</New>
</Configure>
As you can see, because of the way the JNDI resource gets resolved in Jetty, I still need to bundle my postgresql driver in /lib. Alas, but I can at least still test things out locally. Notice that in my DataSource I specify things as java:comp/env/jdbc/groovyblogs, but in jetty-env.xml it needs to be jdbc/groovyblogs. You’ve been warned.
But what about production settings? In my case, I’m deploying to glassfish, so I just need to setup my jdbc connection pool and connection under the “Resources” section of the Glassfish Web Admin tool and I’m in business. Gives me a wealth of options for pool sizes, polling of connections and all that good gear – I can even “ping” the database from the admin tool to make sure it’s configured correctly. Most importantly for me, it gives me a single place for my database name, username and password. I can also do away with the ENC indirection, and just reference the JNDI name directly (jdbc/groovyblogs).
Enough JNDI for one day… Time to head off to jConsole and see what I might be able to monitor about the connection pool *while* the app is running…
8 Comments + Add Comment
Leave a comment
Glen Smith
Archives
- April 2012
- March 2012
- January 2012
- November 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- April 2011
- March 2011
- January 2011
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- June 2005
- May 2005
- April 2005
- March 2005
- February 2005
- January 2005
- December 2004
- November 2004
- October 2004
- September 2004
- August 2004
- July 2004
- June 2004
- May 2004
- March 2004
- February 2004
- January 2004
- December 2003
- November 2003
- October 2003
- September 2003

An article by Glen





Hello,
that’s interesting. But can I deploy a war file with this configuration in a tomcat server?
Gero
Thanks Glen,
for sharing your info, very smart solution, exactly fits my needs (GlassFish+PostgreSQL) and can easily be adopted to other deployment scenes (e.g. add serverName to jetty-env.xml in order to access remote servers).
Regards,
Reiner
Hi!
When i follow your instructions i get following exception when trying to run grails with jndi
java.lang.IllegalStateException: No Constructor:jdbc/data
test test data
on org.mortbay.jetty.webapp.WebAppContext@1747e0f{/wezi,D:grailsWorkspacewezi/web-app}
This is a pretty old post, but it’s the best description I’ve found about getting Grails to work with JNDI for use with Jetty. Unfortunately, I can’t get it to work. My JNDI configuration for the production environment works fine under Tomcat, but when I try to enable JNDI for the test environment (grails test-app), my functional tests blow up complaining with a “javax.naming.NameNotFoundException; remaining name ‘env/myDataSource’”.
I’ve created a jetty-env.xml file for hsqldb that looks like the following:
< ?xml version="1.0"?> < !DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
jdbc/myDataSource
org.hsqldb.jdbcDriver
jdbc:hsqldb:mem:devDB
sa
org.enhydra.jdbc.xapool
and I’ve changed my DataSource.groovy to include the following:
test { dataSource { // see web-app/WEB-INF/jetty-env.xml for JNDI settings dbCreate = "update" jndiName = "java:comp/env/myDataSource" pooled = false // JNDI provides pooling }As I’ve floundered around, I’ve also tried adding a section to the generated web.xml, and added enable.jndi=true to BuildConfig.groovy, but I still end up with the same error.
Any idea what I might be doing wrong?
@Tom that looks totally fine with me. Very weird.
As an aside, the Refactor boys have done a more current and detailed write up on this with Tomcat (might be useful since 1.2 has moved to Tomcat for the inprocess web server).
Tom I think you are missing the word”jdbc” in this line:
jndiName = “java:comp/env/myDataSource”
it should say:
jndiName = “java:comp/env/jdbc/myDataSource”
because you named your JNDI datasource like so: “jdbc/myDataSource”
Prefixing “jdbc/” to a logical name is done by convention and is not a requirement.
hello,
when i run app
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘sessionFactory’: Cannot resolve reference to bean ‘
dataSource’ while setting bean property ‘dataSource’; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean
with name ‘dataSource’: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name jdbc is not bound in this Cont
ext
Very Interesting. It totally work incorrectly for me. I got
java.lang.IllegalStateException: No Constructor: jdbc/data
testtestdata
on org.mortbay.jetty.webapp.WebAppContext@1747e0f{/wezi,D:grailsWorkspacewezi/web-app}
But other case work correctly In Java side.