Using Spring and Open MQ – XA with JOTM Cannot resolve external resource into attachment.

If you are interested in contributing to this FAQ, please read the Contribution Guidelines.

Back to Open MQ


Jspwiki style: center

Please note that these samples are posted for the benefit of the community. These samples are intended to help you understand how you can use Open MQ in various integration and application settings. Use of these samples is at your own risk.

We welcome your feedback – [^mailto:users@mq.java.net]


Jspwiki style: center

%%(text-align:left
------
The following two simple MQ Spring examples integrate MQ with Spring's JtaTransactionManager for XA using JOTM transaction manager and Jencks PooledSpringXAConnectionFactory

A. Instruction
1. Download jar files needed

  • spring.jar - Spring 2.5.5, The Spring Framework
  • jotm.jar - comes with Spring 2.5.5
  • ow_carol.jar howl.jar - dependency of jotm.jar
  • jotm_jrmp_stubs.jar - dependency of jotm.jar
  • jencks-2.0.jar - Jencks 2.0
  • connector.jar - JCA, comes with Spring 2.5.5
  • commons-pool-1.4.jar - Apache Commons Pool, dependency of Jencks 2.0
  • backport-util-concurrent-2.2.jar - dependency of Jencks 2.0
  • commons-logging-1.1.1.jar - dependency of Spring and Jencks
  • aspectjrt.jar aspectjweaver.jar - AspectJ, comes with Spring 2.5.5
  • cglib-nodep-2.1_3.jar- comes with Spring 2.5.5
  • jta.jar - JTA, comes with Spring 2.5.5
  • jms.jar - JMS 1.1
  • imq.jar - MQ 4.3 Client Runtime

2. Compile Example Classes

  • compile MQ dependent class
javac -classpath .:jms.jar:imq.jar MQXAConnectionFactoryFactory.java
  • compile POJO class
javac -classpath .:jms.jar SimpleMessageListener.java
  • compile Spring dependent classes
javac -classpath .:jms.jar:imq.jar:spring.jar SimpleSender.java
javac -classpath .:jms.jar:imq.jar:spring.jar SenderDemo.java
javac -classpath .:jms.jar:imq.jar:spring.jar ConsumerDemo.java

3. Start MQ broker

4. Edit Spring application context configuration files for
the examples if necessary (eg. change broker port)

  • sendercontext.xml for SenderDemo
  • consumercontext.xml for ConsumerDemo

5. Run the examples

java -classpath <list of above jar files> SenderDemo
java -classpath <list of above jar files> ConsumerDemo

B. Spring application context configuration files for the examples
(sendercontext.xml content)

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

<bean id="sender" class="SimpleSender">
      <property name="jmsTemplate" ref="jmsTemplate"/>
</bean>

<!-- sender transaction - follow example from Spring reference documentation -->
<tx:advice id="txAdvice" transaction-manager="transactionmanager">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>
<aop:config>
     <aop:pointcut id="senderOperation" expression="execution(* SimpleSender.*(..))"/>
     <aop:advisor advice-ref="txAdvice" pointcut-ref="senderOperation"/>
</aop:config>

<bean id="connectionfactoryfactory"
     class="MQXAConnectionFactoryFactory">
        <property name="properties">
            <props>
                <prop key="imqAddressList">localhost:7676</prop>
            </props>
        </property>
</bean>

<bean id="connectionfactory"
     factory-bean="connectionfactoryfactory"
     factory-method="createConnectionFactory"/>

<bean id="myqueue" class="com.sun.messaging.Queue">
     <constructor-arg type="java.lang.String" value="myqueue"/>
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
      <property name="connectionFactory" ref="springconnectionfactory"/>
      <property name="defaultDestination" ref="myqueue"/>
      <property name="receiveTimeout" value="20000"/>
</bean>

<bean id="springconnectionfactory" class="org.springframework.jms.connection.SingleConnectionFactory">
      <property name="targetConnectionFactory" ref="jencksconnectionfactory" />
</bean>

<bean id="jencksconnectionfactory" class="org.jencks.pool.PooledSpringXAConnectionFactory">
        <property name="connectionFactory" ref="connectionfactory"/>
        <property name="transactionManager" ref="jotm"/>
</bean>

<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>

<bean id="transactionmanager" class="org.springframework.transaction.jta.JtaTransactionManager">
      <property name="userTransaction" ref="jotm"/>
</bean>

</beans>

(consumercontext.xml content)

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

<bean id="connectionfactoryfactory"
     class="MQXAConnectionFactoryFactory">
        <property name="properties">
            <props>
                <prop key="imqAddressList">localhost:7676</prop>
            </props>
        </property>
</bean>

<bean id="connectionfactory"
     factory-bean="connectionfactoryfactory"
     factory-method="createConnectionFactory"/>

<bean id="myqueue" class="com.sun.messaging.Queue">
     <constructor-arg type="java.lang.String" value="myqueue"/>
</bean>

<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>

<bean id="transactionmanager" class="org.springframework.transaction.jta.JtaTransactionManager">
      <property name="userTransaction" ref="jotm"/>
</bean>

<bean id="springconnectionfactory" class="org.springframework.jms.connection.SingleConnectionFactory">
      <property name="targetConnectionFactory" ref="jencksconnectionfactory" />
</bean>

<bean id="jencksconnectionfactory" class="org.jencks.pool.PooledSpringXAConnectionFactory">
        <property name="connectionFactory" ref="connectionfactory"/>
        <property name="transactionManager" ref="jotm"/>
</bean>

<bean id="consumercontainer"
       class="org.springframework.jms.listener.DefaultMessageListenerContainer">
       <property name="connectionFactory" ref="springconnectionfactory"/>
       <property name="destination" ref="myqueue"/>
       <property name="messageListener" ref="messagelistener"/>
       <property name="transactionTimeout" value="180000"/>
       <property name="receiveTimeout" value="180000"/>
           <property name="sessionTransacted" value="true" />
           <property name="transactionManager" ref="transactionmanager" />
</bean>

<bean id="messagelistener"
      class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
      <constructor-arg>
          <bean class="SimpleMessageListener"/>
      </constructor-arg>
</bean>

</beans>

C. Example Classes

import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.ApplicationContext;

public class SenderDemo {

    public static void main(String[] args) {
        System.out.println("SenderDemo.main() ..");
        ApplicationContext ctx = new FileSystemXmlApplicationContext("./sendercontext.xml");
        SimpleSender sender = (SimpleSender)ctx.getBean("sender");

        System.out.println("SenderDemo.main(): calling sender.sendMessage() ..");
        sender.sendMessage();
    }
}
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.JmsTemplate;

public class SimpleSender {

    private JmsTemplate jmsTemplate;

    public void setJmsTemplate(JmsTemplate template) {
        this.jmsTemplate = template;
    }

    public void sendMessage() {
        System.out.println("SimpleSender.sendMessage() ..");
        final String msg = "Hello, a message from Spring";

        this.jmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
              return session.createTextMessage(msg);
            }
        });
        System.out.println("SimpleSender.sendMessage(): Sent message: "+msg);
    }
}
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.context.ApplicationContext;

public class ConsumerDemo {

    public static void main(String[] args) {

        System.out.println("ConsumerDemo.main() ..");

        ApplicationContext ctx = new FileSystemXmlApplicationContext("./consumercontext.xml");

        ctx.getBean("consumercontainer");
        try {
            System.out.println("ConsumerDemo.main(): Waiting for container shutdown ...");
            while (true) Thread.sleep(5000);
        } catch (Exception e) {
            System.out.println("ConsumerDemo.main(): Got exception: "+e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
        System.out.println("ConsumerDemo.main(): Done!");

        System.exit(0);
    }
}
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class SimpleMessageListener implements MessageListener {

    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                System.out.println(
                "SimpleMessageListener.onMessage(): Received message: "+
                                      ((TextMessage) message).getText());
            }
            catch (JMSException ex) {
                System.out.println(
                "SimpleMessageListener.onMessage(): got exception: "+ex.getMessage());
                ex.printStackTrace();
                throw new RuntimeException(ex);
            }
        }
        else {
            throw new IllegalArgumentException(
            "MessageListener.onMessage(): Message must be of type TextMessage");
        }
    }
}
import java.util.Properties;
import java.util.Enumeration;
import javax.jms.*;

public class MQXAConnectionFactoryFactory {
    private Properties props;

    public void setProperties(Properties props) {
        this.props = props;
    }

    public XAConnectionFactory createConnectionFactory(){
        com.sun.messaging.XAConnectionFactory cf =
                new com.sun.messaging.XAConnectionFactory();
        try{
            Enumeration keys = props.propertyNames();
            while (keys.hasMoreElements()) {
                String name = (String)keys.nextElement();
                String value = props.getProperty(name);
                cf.setProperty(name, value);
            }
        } catch (Exception e){
            throw new RuntimeException(
            "MQConnectionFactoryFactory.createConnectionFactory() failed: "+
            e.getMessage(), e);
        }
        return cf;
    }
}