Monday, April 02, 2012

JNDI with grails and TcServer

Just something to be aware of.

In order to reference JNDI resources from a grails (and probably java spring) app on TC Server there are 2 steps to perform.

1/ Add the jndi name to the tcserver conf/server.xml file. This will declare the jndi name and the resource that it represents. In your head you may assume that this is the only step you need (I know I did)...

This is a configuration object in the conf dir of your tcServer directory
e.g. (Note also have variables e.g. my.url defined in catalina.properties here)

<Resource accessToUnderlyingConnectionAllowed="false"
defaultAutoCommit="true" defaultReadOnly="false"
driverClassName="com.sybase.jdbc3.jdbc.SybDriver"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
initialSize="0" logAbandoned="false" maxActive="8"
maxIdle="8" maxOpenPreparedStatements="0" maxWait="-1"
minEvictableIdleTimeMillis="1800000" minIdle="0"
name="jdbc/myOtherDS" numTestsPerEvictionRun="3"
password="${my.password}" poolPreparedStatements="false"
removeAbandoned="false" removeAbandonedTimeout="300"
testOnBorrow="true" testOnReturn="false"
testWhileIdle="false" timeBetweenEvictionRunsMillis="-1"
type="javax.sql.DataSource" url="${myOther.url}"
username="${myOther.username}" validationQuery="select @@servername" />
<Resource accessToUnderlyingConnectionAllowed="false"
defaultAutoCommit="true" defaultReadOnly="false"
driverClassName="com.ibm.db2.jcc.DB2Driver"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
initialSize="0" logAbandoned="false" maxActive="8" maxIdle="8"
maxOpenPreparedStatements="0" maxWait="-1"
minEvictableIdleTimeMillis="1800000" minIdle="0"
name="jdbc/myDS" numTestsPerEvictionRun="3"
password="${my.password}" poolPreparedStatements="false"
removeAbandoned="false" removeAbandonedTimeout="300"
testOnBorrow="true" testOnReturn="false" testWhileIdle="false"
timeBetweenEvictionRunsMillis="-1"
type="javax.sql.DataSource" url="${my.url}"
username="${my.username}" validationQuery="SELECT 1 from sysibm.sysdummy1" />


2/ You also need to add the jndi name to META_INF/context.xml
This simply creates a mapping from the jndi name to a Java object (Normally a dataSource).

the context.xml is normally part of the source code for the application so will be checked into your source control repository.. You will need a new build if you add or change the data in here. This isn't a big deal really since you will need to add code to deal with the new or updated jndi object at any rate.

Sample

<Context path="myAppUrl" debug="1" reloadable="true" docBase="myAppDocBase" antiResourceLocking="true">
<ResourceLink global="jdbc/myDS" name="jdbc/myDS" type="javax.sql.Datasource"/>
<ResourceLink global="jdbc/myOtherDS" name="jdbc/myOtherDS" type="javax.sql.Datasource"/>
</Context>