Configuring ActiveMQ 5 jms topic in Tomcat 6
For some reason it is quite difficult to find a clear instruction on howto configure ActiveMQ jms topic in tomcat as a JNDI reference and the consume message from it into message driven pojo. I chose to use ActiveMQ 5 since it requires less dependent libraries to run than previous versions.
Start by downloading ActiveMQ 5.0.0 from Apache ActiveMQ site
You need following jars to be located under CATALINA_HOME/lib:
– activemq-core-5.0.0.jar
– commons-logging-1.1.jar
– geronimo-j2ee-management_1.0_spec-1.0.jar (or another jar that has javax.management apis)
– geronimo-jms_1.1_spec-1.0.jar (or another jar that has javax.jms apis)
– geronimo-jta_1.0.1B_spec-1.0.jar (or another jar that has javax.transaction apis)
You can find above libraries from ACTIVEMQ_HOME/lib
That configure the topic and connection factory to CATALINA_HOME/conf/server.xml
<Resource
name="jms/ConnectionFactory"
auth="Container"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="vm://localhost" brokerName="LocalActiveMQBroker"/>
<Resource
name="jms/SampleTopic"
auth="Container"
type="org.apache.activemq.command.ActiveMQTopic"
description="my Topic"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="SAMPLE.TOPIC"/>
Then you need to add resource-link to either CATALINA_HOME/conf/context.xml or webapps META-INF/context.xml
<Context>
....
<ResourceLink global="jms/ConnectionFactory" name="jms/ConnectionFactory" type="javax.jms.ConnectionFactory"/>
<ResourceLink global="jms/SampleTopic" name="jms/SampleTopic" type="javax.jms.Topic"/>
</context>
You also need to add a resource-ref to your webapps web.xml
<resource-ref>
<res-ref-name>jms/ConnectionFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-ref>
<res-ref-name>jms/SampleTopic</res-ref-name>
<res-type>javax.jms.Topic</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Then configure message driven pojo with spring. You should notice that this is really a pojo that does not know anything about jms.
package fi.javaguru.mdp;
public class SamplePojo {
public void doSomething(final String msg) {
System.out.println("Got message: " + msg);
}
}
Spring configuration for consuming messages
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="jms/ConnectionFactory" resource-ref="true"/>
<jee:jndi-lookup id="jmsTopic" jndi-name="jms/SampleTopic"
resource-ref="true" proxy-interface="javax.jms.Topic"/>
<bean id="pojo" class="fi.javaguru.mdp.SamplePojo" />
<bean id="listener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<property name="delegate" ref="pojo"/>
<property name="defaultListenerMethod" value="doSomething"/>
</bean>
<bean id="container" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="messageListener" ref="listener"/>
<property name="destination" ref="jmsTopic"/>
</bean>
</beans>
This sample assumes you are sending String messages to the topic. You could also send other objects as long as the consumer knows about those objects. Thats it for now. I will write another post later that will continue this sample with producing messages to a topic.