Spring and OpenJMS (JMS 1.0.2)
I had a difficult time getting a Spring JmsTemplate configured and connected to my OpenJMS server. There wasn't any complete examples in the Spring documentation. Eventually I did get it working, and I am posting the results here in the hopes that someone else will find it useful.
This configuration fetches the OpenJMS QueueConnectionFactory from JNDI, and sets up a Spring JMS JNDI Destination Resolver to pull named destinations (queues or topics) out of JNDI.
Pass the jmsQueueTemplate or jmsTopicTemplate beans into your own objects as a property, you
can use them to send and receive from any OpenJMS queue or topic.
Spring JmsTemplate Warning
Do not use Spring's JMS Template to read messages from a topic (queues are OK), you will lose messages:
Another gotcha I've seen folks do is to create a MessageConsumer inside one of the SessionCallback methods then wonder why messages are not being received. After the SessionCallback is called, the session will be closed; which will close your consumers too . So if you want to create a MessageConsumer you should create a connection, session and consumer yourself. (BTW it might be nice to make the createConsumer & createSession methods public on JmsTemplate).
(quoted from ActiveMQ's JmsTemplate Gotchas Page)
Application Context XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//Spring//DTD Bean//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<!-- Application Context -->
<beans>
<!-- Property Placeholder Post-Processor (Handles ${variables}) -->
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"><value>classpath:/bootstrap.properties</value></property>
</bean>
<!-- JNDI Environment Template -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">${jms.jndiContextFactory}</prop>
<prop key="java.naming.provider.url">${jms.jndiProviderUrl}</prop>
</props>
</property>
</bean>
<!-- Internal JMS Queue Connection Factory -->
<bean id="internalJmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>${jms.queueConnectionFactoryName}</value>
</property>
</bean>
<!-- Spring Wrapped JMS Queue Connection Factory -->
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory102">
<property name="targetConnectionFactory">
<ref bean="internalJmsQueueConnectionFactory"/>
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
</bean>
<!-- Internal JMS Topic Connection Factory -->
<bean id="internalJmsTopicConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>${jms.topicConnectionFactoryName}</value>
</property>
</bean>
<!-- Spring Wrapped JMS Queue Connection Factory -->
<bean id="jmsTopicConnectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory102">
<property name="targetConnectionFactory">
<ref bean="internalJmsTopicConnectionFactory"/>
</property>
<property name="pubSubDomain">
<value>true</value>
</property>
</bean>
<!-- JMS Destination Resolver -->
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
<!-- JMS Queue Template -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate102">
<property name="connectionFactory">
<ref bean="jmsQueueConnectionFactory"/>
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver"/>
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
<property name="receiveTimeout">
<value>2000</value>
</property>
</bean>
<!-- JMS Topic Template -->
<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate102">
<property name="connectionFactory">
<ref bean="jmsTopicConnectionFactory"/>
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver"/>
</property>
<property name="pubSubDomain">
<value>true</value>
</property>
</bean>
</beans>
