working spring message driven POJO (MDP) with Bitronix and no j2ee container

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

working spring message driven POJO (MDP) with Bitronix and no j2ee container

Simon-2745

I have just had the pleasure of getting Bitronix up and running for
Spring Message Driven POJOs (MDPs) in JUnit outside of any J2EE
container using Spring. I have a maven built sample project that tests
rollback of database writes made by a MDP under a global (jms+jdbc)
transaction. Any suggestions about which wiki should I post and document
the sample code that tests the Spring configuration below?

The code and configuration was based on Murali Kosaraju's JavaWorld.com
article "XA transactions using Spring - JTA/XA transactions without the
J2EE container"
http://www.javaworld.com/javaworld/jw-04-2007/jw-04-xa.html where he
used a beta version of Bitronix. The MDP code was taken from
http://static.springframework.org/spring/docs/2.5.x/reference/jms.html

The library versions I have used are:

* junit:junit:3.8.1
* org.codehaus.btm:btm:1.3
* org.slf4j:slf4j-jdk14:1.5.2
* org.apache.derby:derby:10.4.2.0
* org.springframework:spring:2.5.6
* log4j:log4j:1.2.15
* activemq:activemq-core:3.2.4

The spring configuration follows below.

Kindest Regards,

Simon

<?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"
    xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd
    ">

    <!-- Bitronix Transaction Manager embedded configuration -->
    <bean id="btmConfig" factory-method="getConfiguration"
        class="bitronix.tm.TransactionManagerServices">
        <property name="serverId" value="spring-btm" />
    </bean>

    <!-- create BTM transaction manager -->
    <bean id="BitronixTransactionManager"
factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices"
depends-on="btmConfig,xaDataSource"
        destroy-method="shutdown" />

    <!-- Spring JtaTransactionManager -->
    <bean id="jtaTransactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager"
ref="BitronixTransactionManager" />
        <property name="userTransaction" ref="BitronixTransactionManager" />
    </bean>

    <!-- XA DataSource -->
    <bean id="xaDataSource"
class="bitronix.tm.resource.jdbc.PoolingDataSource"
        init-method="init" destroy-method="close">
        <property name="className"
value="org.apache.derby.jdbc.EmbeddedXADataSource" />
        <property name="uniqueName" value="derby1" />
        <property name="minPoolSize" value="0" />
        <property name="maxPoolSize" value="3" />
        <property name="driverProperties">
            <props>
                <prop key="databaseName">derbydb</prop>
                <prop key="createDatabase">create</prop>
            </props>
        </property>
    </bean>

    <!-- Raw untransactional DAO  -->
    <bean id="messageSequenceDaoImpl"
class="com.acme.springjta.MessageSequenceDaoImpl">
        <property name="dataSource" ref="xaDataSource" />
    </bean>

    <!-- Transactional wrapper of the DAO -->
    <bean id="messageSequenceDAO"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="jtaTransactionManager" />
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED, -Exception
                </prop>
            </props>
        </property>
        <property name="target" ref="messageSequenceDaoImpl" />
    </bean>

    <!-- XA JMS Connection Factory -->
    <bean id="xaJmsConnectionFactory"
class="bitronix.tm.resource.jms.PoolingConnectionFactory"
        init-method="init" destroy-method="close">
        <property name="className"
value="org.activemq.ActiveMQXAConnectionFactory" />
        <property name="uniqueName" value="activemq" />
        <property name="minPoolSize" value="1" />
        <property name="maxPoolSize" value="1" />
        <property name="allowLocalTransactions" value="true" />
        <property name="user" value="user" />
        <property name="password" value="password" />
        <property name="driverProperties">
            <props>
                <prop key="brokerURL">vm://localhost</prop>
            </props>
        </property>
    </bean>

    <!-- JMS Destination -->
    <bean id="destination" class="org.activemq.message.ActiveMQQueue">
        <constructor-arg value="test.queue" />
    </bean>

    <!-- JMS Template for sending messages -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="xaJmsConnectionFactory" />
        <property name="defaultDestination" ref="destination" />
    </bean>

    <!-- Service for sending JMS messages -->
    <bean id="defaultTextMessageSender"
class="com.acme.springjta.DefaultTextMessageSender">
        <property name="jmsTemplate" ref="jmsTemplate" />
    </bean>

    <!-- Transactional wrapper of the service for sending JMS message -->
    <bean id="textMessageSender"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="jtaTransactionManager" />
        <property name="transactionAttributes">
            <props>
                <prop key="*">PROPAGATION_REQUIRED, -Exception
                </prop>
            </props>
        </property>
        <property name="target" ref="defaultTextMessageSender" />
    </bean>

    <!-- Our Message Driven POJO -->
    <bean id="textMessageDelegate"
class="com.acme.springjta.DefaultTextMessageDelegate" />

    <!-- JMS Listener Delegates to our Message Driven POJO -->
    <bean id="messageListener"

class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
        <constructor-arg ref="textMessageDelegate" />
        <property name="defaultListenerMethod" value="receive" />
        <!-- we don't want automatic message context extraction -->
        <property name="messageConverter">
            <null />
        </property>
    </bean>

    <!-- JMS Container For Receiving Messages Under XA -->
    <bean id="jmsContainer"

class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="xaJmsConnectionFactory" />
        <property name="destination" ref="destination" />
        <property name="messageListener" ref="messageListener" />
        <property name="transactionManager" ref="jtaTransactionManager" />
    </bean>
</beans>



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: working spring message driven POJO (MDP) with Bitronix and no j2ee container

Ludovic Orban
Administrator
Thanks for sharing your config.

I actually planned to update the Spring documentation page and include both JDBC and JMS examples in it but as usual I lacked time.

Commenting the page directly in Confluence (just like you did) probably is the best way to contribute configuration examples.