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:

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…