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.