Wednesday, August 25, 2010

Grails, Tomcat, Named Entries and the resources.groovy

Post one, here we go.

The stack:

Grails 1.3.2

Oracle

Tomcat 5.5

Java 1.5.0_16

The Context:

We were asked to rebuild a website from scratch but replicate an existing site verbatim. Part of this work required that we integrate with an existing jar file that was supposed to handle the authentication aspects of the site. Communication through this jar file was the only database connectivity we needed for the whole site. The existing jar file used a JNDI name to reference the database connect. The code form the jar that creates the connection is a simple JDNI context lookup:

Context ctx = new InitialContext();
dataSource = (javax.sql.DataSource) ctx.lookup([JNDI NAME]);



The Solution:

We attempted to use the Grails Tomcat plugin and "grails.naming.entries" to manage these connections. Based on the
Grails Tomcat plugin documentationwe created the entries and moved forward.


The Issue(s):

The first issue was a confusion between how the Grails integration test initialize the entries and how the actual application works. Integration tests will create the database connection successfully with just the "grails.naming.entries" in place. The application (run-app) will not create the connection without a "resources.groovy" defined. The exception you will see should be similar to:



ERROR util.MVConnectionManager - NamingException in ConnectionManager

javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

at org.apache.naming.NamingContext.lookup(NamingContext.java:770)

at org.apache.naming.NamingContext.lookup(NamingContext.java:140)

at org.apache.naming.NamingContext.lookup(NamingContext.java:781)

at org.apache.naming.NamingContext.lookup(NamingContext.java:140)

at org.apache.naming.NamingContext.lookup(NamingContext.java:781)

at org.apache.naming.NamingContext.lookup(NamingContext.java:153)

at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137)

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


Second issue is the deployed application will not create a database connection unless a context.xml file is defined. In this case you will see a similar exception outputted in the logs for the application as above. It is unclear whether the named entries are required for a deployed war but we included them in a environment config node. Dropping a context.xml file is simple enough though. Just ensure that the resource name and the name in resources.groovy match up appropriately:



<context path="">
<resource name="jdbc/poolName">
... maxActive="20" /></context>


beans = { xmlns jee:"http://www.springframework.org/schema/jee" jee.'jndi-lookup'(id: "authDbDataSource", 'jndi-name': "java:comp/env/jdbc/poolName") }

To deploy the context.xml file we placed the context.xml within the "./webapps/[appName]/META-INF/context.xml" path.

The final issue is it appears that Tomcat takes a snapshot of the context.xml file when the application starts but does not necessarily update this file when it is updated in the deployed war. Tomcat will store a copy of the context.xml file in the path "[tomcatHome]/conf/Catalina/localhost/[appName].xml". If you make updates to the context.xml file in the war, these changes don't appear to be updated in the Tomcat version of the file. This bit us because we had errors in our initial version of context.xml but subsequent changes never seemed to fix the issue. This combined with other issue of Tomcat not refresh the exploded war on start-up forced us to create a shell script that deletes all previous data for the application so we know there is no dirty data lurking around.

Useful Links:

http://markmail.org/message/z7nhiq3m2z3iryre

http://www.grails.org/doc/1.3.x/guide/3.%20Configuration.html

http://www.jroller.com/berni/entry/grails_deployment_issues

http://refactor.com.au/blog/idiots-guide-tomcat-6-grails-jndi-datasource

Final Complaints:

The grails documentation for the Tomcat plugin specify we use a jee."jndi-lookup" to specify the resource name but there is almost no documentation as to what any of that means. Could be useful.

Productivity Lost

6 hours


Where's the documentation for this ....

Hello internets. You happen to have stumble upon the ramblings of one very annoyed software engineer with a desire that people never have to waist their time looking for answers that I've already found.