Tomcat Datasource configuration

I describe here my favorite solution to define the datasource of my web applications.

To do that in Tomcat :

  1. Copy the JDBC driver jar into the Tomcat lib directory
  2. define the datasource in the file server.xml:
     <GlobalNamingResources>
    
        <Resource 
            auth="Container" 
            driverClassName="oracle.jdbc.OracleDriver" 
            maxActive="20" 
            maxIdle="10" 
            maxWait="-1" 
            name="jdbc/myGlobalDatasource" 
            password="password" 
            type="javax.sql.DataSource" 
            url="jdbc:oracle:thin:@[server]:[port]:[sid]" 
            username="user"/>
    
    </GlobalNamingResources>
  3. map this datasource to your application using its context.xml file:
    <ResourceLink 
        global="jdbc/globalDatasource" 
        name="jdbc/applicationDatasource" 
        type="javax.sql.DataSource"/>
  4. And now, when you want to use it (using Spring):
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jdbc/applicationDatasource" />
        <property name="resourceRef" value="true" />
    </bean>

Done!

This example uses an Oracle connection but it can be easily adapted for another database.

JBoss transaction manager (Non XA)

This is my configuration for using the transaction manager implementation provided by JBoss outside of a JEE container. This configuration works for database transaction but not for JMS transaction;
The configuration is done with Spring which delegates the transaction management to the JBoss implementation. Even if I used all the stuff to be able to manage XA transactions, it is not working with JMS. It seems that the messages are not included in the transaction and with the lack of clear documentation to properly configure it, I finally gave up and decided to use an alternative provider.
I present here the configuration to use the JBoss transaction manager I used for database transaction management:

<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven/>
<tx:jta-transaction-manager/> 

<!--     Transactionmanager Config  (uses CORBA??) -->
<!--     <bean class="com.arjuna.ats.jta.TransactionManager" factory-method="transactionManager" id="arjunaTransactionManager"></bean> -->
<!--     <bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction" id="arjunaUserTransaction"></bean> -->

<!--     Transactionmanager Config  (local, without CORBA??-again...) -->
<bean class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple" id="arjunaTransactionManager"></bean>
<bean class="com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple" id="arjunaUserTransaction"></bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
    <property name="transactionManager" ref="arjunaTransactionManager"/>
    <property name="userTransaction" ref="arjunaUserTransaction"/>
</bean>

<!-- Datasource config (use XA!)-->
<bean id="ifxXADataSource" class="com.informix.jdbcx.IfxXADataSource">
    <property name="user" value="${user}" />
    <property name="password" value="${pwd}" />
    <property name="serverName" value="${serverName}" /> 
    <property name="databaseName" value="${dbName}" /> 
    <property name="portNumber" value="${port}" />
    <property name="ifxIFXHOST" value="${host}" /> 
    <property name="ifxIFX_LOCK_MODE_WAIT" value="5" /> 
    <property name="ifxIFX_XASPEC" value="Y" />
    <property name="ifxDB_LOCALE" value="en_us.819" />        
</bean>

<bean id="dsXAConnectionFactory" class="org.apache.commons.dbcp.managed.DataSourceXAConnectionFactory">
    <constructor-arg><ref bean="arjunaTransactionManager"></ref></constructor-arg>
    <constructor-arg><ref bean="ifxXADataSource"></ref></constructor-arg>
</bean>

<bean id="pool" class="org.apache.commons.pool.impl.GenericObjectPool">
    <property name="maxActive" value="20"/>
    <property name="minIdle" value="5"/>
</bean>

<bean id="poolableConnectionFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory">
    <constructor-arg name="connFactory" ref="dsXAConnectionFactory"/>
    <constructor-arg name="pool" ref="pool"/>
    <constructor-arg name="stmtPoolFactory"><null></null></constructor-arg>
    <constructor-arg name="validationQuery"><null></null></constructor-arg>
    <constructor-arg name="defaultReadOnly" value="false"/>
    <constructor-arg name="defaultAutoCommit" value="false"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.managed.ManagedDataSource" depends-on="poolableConnectionFactory">
    <constructor-arg name="pool" ref="pool"/>
    <constructor-arg name="transactionRegistry" value="#{dsXAConnectionFactory.getTransactionRegistry()}"/>
</bean>

Maven dependencies:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.framework.version>4.0.0.RELEASE</spring.framework.version>
    <apache.tomcat.version>7.0.50</apache.tomcat.version>
</properties>

<dependencies>
    <!-- Logging dependencies -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>ant</groupId>
        <artifactId>ant-apache-log4j</artifactId>
        <version>1.6.5</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>com.informix.jdbc</groupId>
        <artifactId>ifxjdbc</artifactId>
        <version>4.10</version>
    </dependency>
    <dependency>
        <groupId>com.informix.jdbc</groupId>
        <artifactId>ifxjdbcx</artifactId>
        <version>4.10</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.jbossts</groupId>
        <artifactId>narayana-all</artifactId>
        <version>4.17.16.Final</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.transaction</groupId>
        <artifactId>jboss-transaction-api_1.1_spec</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.jbossts.jts</groupId>
        <artifactId>jbossjts-jacorb</artifactId>
        <version>4.17.13.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.logging</groupId>
        <artifactId>jboss-logging</artifactId>
        <version>3.1.0.GA</version>
    </dependency>
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>
</dependencies>

Simple Spring configuration

Spring configuration for use of a simple transaction manager (non XA). The data source must be defined in a JNDI repository (Tomcat in my case).

application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<bean id="entityManagerFactory"
                class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
                <property name="generateDdl" value="false" />
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.connection.SetBigStringTryClob">true</prop> <!-- should be done via system properties -->
                <prop key="hibernate.jdbc.batch_size">0</prop>
                <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
            </props>
        </property>
    </bean>

	<!-- DBCP data source -->

	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="jdbc/applicationDatasource" />
		<property name="resourceRef" value="true" />
	</bean>

	<!-- the transaction manager -->
	<tx:annotation-driven transaction-manager="txManager" />

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<!-- exceptions translation -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

	<!-- persistance annotations -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

</beans>

Maven dependencies:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.framework.version>3.0.7.RELEASE</spring.framework.version>
    <hibernate.version>3.6.9.Final</hibernate.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
</dependencies>

To start automatically the Spring Ccontext, add in your web.xml:

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>