Tag Archive | tomcat

Apache ActiveMQ and Tomcat

Today I want to investigate how to integrate JMS functionality into a web application running within a Tomcat servlet container (7.x). As we do not use a fully fledged application server, we have to care about registering the ConnectionFactory and Queue within the JNDI context. In this exmple I chose Apache ActiveMQ as a JMS provider. As a simple example, I want to have two Servlets: The first Servlet pushes messages into a queue, whereas the second Servlet pulls them out of the queue and displays the messages as an HTML page.

Let’s add the necessary maven dependencies to our pom.xml:

		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-core</artifactId>
			<version>5.7.0</version>
		</dependency>
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-web-api</artifactId>
			<version>6.0</version>
			<scope>provided</scope>
		</dependency>

As Tomcat has only a static JNDI, we add the ConnectionFactory and the Queue via the context.xml:

<?xml version='1.0' encoding='utf-8'?>
<Context>
    <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"
            useEmbeddedBroker="true"/>

    <Resource name="jms/queue/MyQueue"
              auth="Container"
              type="org.apache.activemq.command.ActiveMQQueue"
              factory="org.apache.activemq.jndi.JNDIReferenceFactory"
              physicalName="MY.TEST.FOO.QUEUE"/>
</Context>

Let’s setup a simple Servlet that listens to the URL /sendMessage:

@WebServlet(name = "SendMessageServlet", urlPatterns = "/sendMessage")
public class SendMessageServlet extends HttpServlet {

    private static final Logger logger = LoggerFactory.getLogger(SendMessageServlet.class);

    @Override
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
    	logger.info("doGet() called");
    	String parameter = getTextParameter(httpServletRequest);
        sendMessage(parameter);
        writeResponse(httpServletResponse, parameter);
    }

[...]

}

The text to send is given as a GET-Parameter to the URL. The method sendMessage() contains the relevant code. Here we can access the ConnectionFactory through our JNDI Context:

            InitialContext initCtx = new InitialContext();
            ConnectionFactory connectionFactory = (ConnectionFactory) initCtx.lookup("java:comp/env/jms/ConnectionFactory");
            Connection connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer((Destination) initCtx.lookup("java:comp/env/jms/queue/MyQueue"));

Thus, sending a text message to the queue is quite simple:

            TextMessage testMessage = session.createTextMessage();
            testMessage.setText(text);
            testMessage.setStringProperty("aKey", "someRandomTestValue");
            producer.send(testMessage);

Now it is time to setup a second Servlet that enables us to read all messages from the queue. The code for the sceleton is quite similar to the first Servlet:

@WebServlet(name = "ReceiveMessageServlet", urlPatterns = "/receiveMessage")
public class ReceiveMessageServlet extends HttpServlet {

	private static final Logger logger = LoggerFactory.getLogger(ReceiveMessageServlet.class);

	@Override
	protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
			throws ServletException, IOException {
		logger.info("doGet() called");
		Optional<String> text = receiveMessages();
		writeRepsonse(httpServletResponse, text);
	}

[...]
}

In our receiving Servlet we use the following code to create a QueueReceiver:

InitialContext initCtx = new InitialContext();
QueueConnectionFactory connectionFactory = (QueueConnectionFactory) initCtx.lookup("java:comp/env/jms/ConnectionFactory");
QueueConnection queueConnection = connectionFactory.createQueueConnection();
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) initCtx.lookup("java:comp/env/jms/queue/MyQueue");
QueueReceiver receiver = queueSession.createReceiver(queue);

Finally, we can receive the text message, we have sent before:

queueConnection.start();
try {
	Message m = receiver.receive(1000);
	if (m != null && m instanceof TextMessage) {
		TextMessage tm = (TextMessage) m;
		text = Optional.of(tm.getText());
		logger.debug(String.format("Received TextMessage with text '%s'.", text));
	} else {
		logger.debug(String.format("No TextMessage received: '%s'", m));
	}
} finally {
	queueSession.close();
	queueConnection.close();
}

The whole source code can be found on github: https://github.com/siom79/jms-and-tomcat.