/, Spring/Spring JMS Tutorial with ActiveMQ

Spring JMS Tutorial with ActiveMQ

In this post I’ll look at Springs messaging support and how it can be used to integrate with Message Oriented Middleware (MOM) offerings such as Apache ActiveMQ. Although the sample application in this post will use ActiveMQ as its message broker, the application itself is vendor agnostic and can  integrate with any JMS compliant messaging platform. I’ve kept the application as loosely coupled from ActiveMQ as possible and will highlight the bits that would need to change if you were to choose another message platform such as IBM MQSeries.

Tech Stack

The sample code in this post will be built and deployed as a simple web application. Obviously this doesn’t have to be the case but I’ve chosen to build a web app as these type of enterprise integration components tend to be deployed as web applications in the real world. The sample app will be built using the following stack.
  • Apache ActiveMQ – JMS Message Broker(not part of the actual application but used to test our applications JMS fucntionality)
  • Spring 3.1
  • Maven
  • Tomcat

Setting up ActiveMQ

If you don’t already have ActiveMQ you’ll need to download it at http://activemq.apache.org/download.html The latest version at the time of writing is 5.6.0. To set up ActiveMQ follow the steps below.

  1. Copy the downloaded zip to C:Program Files and unzip.
  2. Open a command window and cd to C:Program Filesapache-activemq-5.6.0-binapache-activemq-5.6.0bin.
  3. Start ApacheMQ by calling activemq.bat

ActiveMQ should start up as shown in figure 1.0 below.

Figure 1.0 ActiveMQ Startup

Now that ActiveMQ has started we can open the admin console by navigating to http://localhost:8161/admin/index.jsp. On the home page we’ll see some information about the broker and some administration menu options.

Figure 2.0 ActiveMQ Admin Console

Next we need to create 2 new Queues, one that our sample application will consume messages from and another Queue that we’ll write messages to. Click on the Queues link and create a new Queue by entering a Queue name and clicking submit. For our sample application we’ll create 2 Queues, TestQueueOne and TestQueueTwo as shown in figure 3.0 below.

Figure 3.0 Create New Queues

Now that we have our message broker set up lets take start building an application to use it.

Creating the Project

We’ll start off by creating a simple Spring web project like the one shown in figure 4.0 below.

Figure 4.0 Project Structure

Spring Configuration

We’ll start by defining the Spring configuration for our application. I’ve commented the configuration below to help explain the main components. The most important parts are the DefaultMessageListenerContainer (used to consume messages) and the JMSTemplate (used to put message onto a queue).
<?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:context="http://www.springframework.org/schema/context"  
               xmlns:jee="http://www.springframework.org/schema/jee"  
               xsi:schemaLocation="http://www.springframework.org/schema/beans  
                                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
                                     http://www.springframework.org/schema/context  
                                     http://www.springframework.org/schema/context/spring-context-3.0.xsd  
                                     http://www.springframework.org/schema/beans  
                                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
                                     http://www.springframework.org/schema/jee  
                                     http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">  
   
   
      <!-- Use Springs JNDI support to look up JMS Connection Factory and Queue definitions from the  
           container. This means that specific connection details are not embedded in the application  
       -->  
      <jee:jndi-lookup id="mqConnectionFactory" jndi-name="java:comp/env/jms/mqConnectionFactory" />  
      <jee:jndi-lookup id="testQueueOne" jndi-name="java:comp/env/jms/testQueueOne" />  
      <jee:jndi-lookup id="testQueueTwo" jndi-name="java:comp/env/jms/testQueueTwo" />  
   
      <!-- Our message listener implementation that implements the JMS MessageListener interface and implements the  
            onMessage method to process incoming messages  
       -->  
      <bean id="testMessageListener" class="com.blog.spring.jms.TestMessageListener">  
         <property name="testMessageSender" ref ="testMessageSender" />  
      </bean>  
   
      <!-- DefaultMessageListenerConatiner is the Spring equivalent to an EJB Message Driven Bean.  
         It polls and consumes messages from a JMS queue. The configuration below is as follows  
   
         1. connectionFactory - the connection factory definition used to connect to the Message Broker  
            which in our case is Active MQ  
         2. destination - the Queue which the MessageListener container is listening on from incoming messages  
         3. messageListener - the implementation class that will actually handle the incoming messages. The  
            DeafultMesssageListener takes messages from the queue and passes them to the message listener for  
            processing. We've defined our message listener above (testMessageListener)  
         4. concurrentConsumers - this is the number of threads that the DeafultMesaegListenerContainer will  
            spawn to handle incoming messages. The default is 1 but in our application we'll have 2 separate  
            threads processing incoming messages.  
       -->  
      <bean id="poiMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
         <property name="connectionFactory" ref ="mqConnectionFactory" />  
         <property name="destination" ref ="testQueueOne"/>  
         <property name="messageListener" ref ="testMessageListener"/>  
         <property name="concurrentConsumers" value="2" />  
      </bean>  
   
      <!-- MessageSender is a simple POJO that we supply with a JMSTemplate and  
           the Queue that we want to send messages to  
       -->  
      <bean id="testMessageSender" class="com.blog.spring.jms.TestMessageSender">  
         <property name="jmsTemplate" ref="jmsTemplate"/>  
         <property name="testQueue" ref="testQueueTwo"/>  
      </bean>  
   
      <!-- JMSTemplate is a Spring template that allows us to communicate with  
           a message broker via JMS. JMSTemplate takes care of boiler plate code such as exception handling  
           and resource management such as connection pooling. This allows us concentrate on solving the 'business'  
           problem. We supply the JMS template with the connection factory mentioned above  
       -->  
      <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
         <property name="connectionFactory" ref="mqConnectionFactory" />  
      </bean>  
   
 </beans>  

JMS Resource Configuration

Next we’ll configure the ActiveMQ Connection Factory and Message Queues which we referenced on lines 19 to 21 above. These resources are defined in context.xml, a configuration file that Tomcat uses to look up runtime resources. This approach allows us to define connection details on the Servlet Container and outside of the actual application, which ensures that our application is not tightly coupled to the the JMS implementation. The resource lookups in context.xml is the only place where we reference ActiveMQ specifics. The application itself does not contain any reference to ActiveMQ, which means that we could easily switch to another JMS broker without changing any code in our application. To integrate with a different JMS broker all we’d need to do is update the context.xml to lookup Connection Factory and Queue definitions specific to our new JMS implementation, IBM MQSeries for example. Our context.xml is defined below.

<?xml version="1.0" encoding="UTF-8"?>  
<Context>  
  
  <!--  
        Active MQ Connection Factory manages pooled connections  
        to the ActiveMQ broker. Tomcat will connect with the  
        broker using a TCP connection on port 61616 - this is the  
        default port for ActiveMQ  
  -->  
   <Resource name="jms/mqConnectionFactory"  
             auth="Container"  
             type="org.apache.activemq.ActiveMQConnectionFactory"  
             description="JMS Connection Factory"  
             factory="org.apache.activemq.jndi.JNDIReferenceFactory"  
             brokerURL="tcp://localhost:61616" />  
   
   <!--  
         This is a reference to the first Queue we defined  
         earlier in the ActiveMQ admin console  
   -->  
   <Resource name="jms/testQueueOne"  
             auth="Container"  
             type="org.apache.activemq.command.ActiveMQQueue"  
             factory="org.apache.activemq.jndi.JNDIReferenceFactory"  
             physicalName="TestQueueOne"/>  
   
   <!--  
         This is a reference to the second Queue we defined  
         earlier in the ActiveMQ admin console  
   -->  
   <Resource name="jms/testQueueTwo"  
             auth="Container"  
             type="org.apache.activemq.command.ActiveMQQueue"  
             factory="org.apache.activemq.jndi.JNDIReferenceFactory"  
             physicalName="TestQueueTwo"/>  
   
 </Context>  

The final part of our application configuration is web.xml. Here we simply define the context loader listener and point it at the Spring configuration file we defined earlier.

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
           xmlns="http://java.sun.com/xml/ns/javaee"  
           xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
           id="WebApp_ID"  
           version="2.5">  
  
      <!--  
           Main configuration file for this Spring web application.  
      -->  
      <context-param>  
           <param-name>contextConfigLocation</param-name>  
           <param-value>  
                /WEB-INF/config/spring-config.xml  
           </param-value>  
      </context-param>  
   
      <!--  
           Loads the Spring web application context using the config file defined above.  
      -->  
      <listener>  
           <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
      </listener>  
   
 </web-app>  

Message Listener

Now we’re ready to start writing some code. You may be glad to know that you that don’t have to write very much code to consume messages from a JMS broker. In fact all we need is a class that implements the MessageListener interface – we override the onMessage method which is then invoked by the DefaultMessageListenerContainer (defined earlier) when a message is read from the queue. Our implementation of onMessage is very straight forward – we simply log the incoming message and then pass it to the message sender (defined later). The Message Listener class is defined below.

package com.blog.spring.jms;  
  
import javax.jms.JMSException;  
import javax.jms.Message;  
import javax.jms.MessageListener;  
import javax.jms.TextMessage;  
import org.apache.log4j.Logger;  
  
 /**  
  * Class handles incoming messages  
  *  
  * @see PointOfIssueMessageEvent  
  */  
 public class TestMessageListener implements MessageListener  
 {  
   
      private TestMessageSender messageSender_i;  
      private static final Logger logger_c = Logger.getLogger(TestMessageListener.class);
   
      /**  
       * Method implements JMS onMessage and acts as the entry  
       * point for messages consumed by Springs DefaultMessageListenerContainer.  
       * When DefaultMessageListenerContainer picks a message from the queue it  
       * invokes this method with the message payload.  
       */  
      public void onMessage(Message message)  
      {  
           logger_c.debug("Received message from queue [" + message +"]");  
   
           /* The message must be of type TextMessage */  
           if (message instanceof TextMessage)  
           {  
                try  
                {  
                     String msgText = ((TextMessage) message).getText();  
                     logger_c.debug("About to process message: " + msgText);  
   
                     /* call message sender to put message onto second queue */  
                     messageSender_i.sendMessage(msgText);  
   
                }  
                catch (JMSException jmsEx_p)  
                {  
                     String errMsg = "An error occurred extracting message";  
                     logger_c.error(errMsg, jmsEx_p);  
                }  
           }  
           else  
           {  
                String errMsg = "Message is not of expected type TextMessage";  
                logger_c.error(errMsg);  
                throw new RuntimeException(errMsg);  
           }  
      }  
   
      /**  
       * Sets the message sender.  
       *  
       * @param messageSender_p the new message sender  
       */  
      public void setTestMessageSender(TestMessageSender messageSender_p)  
      {  
           this.messageSender_i = messageSender_p;  
      }  
 }  
   

Message Sender

Now that our application can consume messages lets take a look at how we push messages onto a queue. We defined a JMSTemplate in the Spring configuration earlier – this class provides a convenient way of pushing messages onto a queue and saves us from having to write boiler plate code for opening and closing connections, handling JMS exceptions etc. This allows the developer to simply specify a queue and the message payload that you want to push onto that queue.

package com.blog.spring.jms;  
  
import javax.jms.JMSException;  
import javax.jms.Queue;  
import org.apache.log4j.Logger;  
import org.springframework.jms.core.JmsTemplate;  
import org.springframework.stereotype.Service;  
  
/**  
  * The TestMessageSender class uses the injected JMSTemplate to send a message  
  * to a specified Queue. In our case we're sending messages to 'TestQueueTwo'  
  */  
 @Service  
 public class TestMessageSender  
 {  
      private JmsTemplate jmsTemplate_i;  
      private Queue testQueue_i;  
      private static final Logger logger_c = Logger .getLogger(TestMessageSender.class);  
   
      /**  
       * Sends message using JMS Template.  
       *  
       * @param message_p the message_p  
       * @throws JMSException the jMS exception  
       */  
      public void sendMessage(String message_p) throws JMSException  
      {  
           logger_c.debug("About to put message on queue. Queue[" + testQueue_i.toString() + "] Message[" + message_p + "]");  
           jmsTemplate_i.convertAndSend(testQueue_i, message_p);  
      }  
   
      /**  
       * Sets the jms template.  
       *  
       * @param template the jms template  
       */  
      public void setJmsTemplate(JmsTemplate tmpl)  
      {  
           this.jmsTemplate_i = tmpl;  
      }  
   
      /**  
       * Sets the test queue.  
       *  
       * @param queue the new test queue  
       */  
      public void setTestQueue(Queue queue)  
      {  
           this.testQueue_i = queue;  
      }  
 }  

Testing the Application

Now that the application is complete lets test it. Using the ActiveMQ admin console we’ll put a message onto TestQueueOne. Conveniently you can tell the broker to submit the message as may times as you like. We’ll ask the broker to submit our message 100 times so that we have time to see  it get picked up and processed in the eclipse console. When we put a message onto TestQueueOne we should see the following

  1. DefaultMessageListenerContainer will pick up the next message from TestQueuOne and invoke the onMessage method in our Message listener class with the message payload.
  2. onMessage will log the message payload and then call the TestMessageSender sendMessage with the message we’ve just received.
  3. TestMessageSender will use the JMSTemplate to put the message onto TestQueueTwo.

To test the application follow the steps below.

  • In the ActiveMQ admin console go to the TestQueueOne definition and click the SendTo link. Add a message and set the ‘Number of Messages to Send’ to 100. This will ensure that broker puts the message onto the queue 100 times.

Figure 5.0 Send JMS Message

  • Click Send. 100 messages will be put onto the queue and you should see the application log the consumption of each message as shown in the log extract below.
DEBUG: [Sep-16 22:59:29,911] spring.jms.TestMessageListener - Received message from queue [ActiveMQTextMessage {commandId = 96, responseRequired = false, messageId = ID:motown-58007-1347813056932-3:4:1:1:92, originalDestination = null, originalTransactionId = null, producerId = ID:motown-58007-1347813056932-3:4:1:1, destination = queue://TestQueueOne, transactionId = null, expiration = 0, timestamp = 1347832725483, arrival = 0, brokerInTime = 1347832725510, brokerOutTime = 1347832766192, correlationId = , replyTo = null, persistent = false, type = , priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@855da06, marshalledProperties = org.apache.activemq.util.ByteSequence@3c5cc430, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = null}]  
 DEBUG: [Sep-16 22:59:29,911] spring.jms.TestMessageListener - About to process message: Test Message!!  
 DEBUG: [Sep-16 22:59:29,911] spring.jms.TestMessageSender - About to put message on queue. Queue[queue://TestQueueTwo] Message[Test Message!!]  
 DEBUG: [Sep-16 22:59:29,947] spring.jms.TestMessageListener - Received message from queue [ActiveMQTextMessage {commandId = 97, responseRequired = false, messageId = ID:motown-58007-1347813056932-3:4:1:1:93, originalDestination = null, originalTransactionId = null, producerId = ID:motown-58007-1347813056932-3:4:1:1, destination = queue://TestQueueOne, transactionId = null, expiration = 0, timestamp = 1347832725483, arrival = 0, brokerInTime = 1347832725510, brokerOutTime = 1347832766192, correlationId = , replyTo = null, persistent = false, type = , priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@6e544a45, marshalledProperties = org.apache.activemq.util.ByteSequence@5fd83099, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = null}]  
 DEBUG: [Sep-16 22:59:29,947] spring.jms.TestMessageListener - About to process message: Test Message!!  
 DEBUG: [Sep-16 22:59:29,948] spring.jms.TestMessageSender - About to put message on queue. Queue[queue://TestQueueTwo] Message[Test Message!!]  
 DEBUG: [Sep-16 22:59:29,986] spring.jms.TestMessageListener - Received message from queue [ActiveMQTextMessage {commandId = 98, responseRequired = false, messageId = ID:motown-58007-1347813056932-3:4:1:1:94, originalDestination = null, originalTransactionId = null, producerId = ID:motown-58007-1347813056932-3:4:1:1, destination = queue://TestQueueOne, transactionId = null, expiration = 0, timestamp = 1347832725483, arrival = 0, brokerInTime = 1347832725510, brokerOutTime = 1347832766192, correlationId = , replyTo = null, persistent = false, type = , priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@6a5ebdf7, marshalledProperties = org.apache.activemq.util.ByteSequence@7209d9af, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = null}]  
 DEBUG: [Sep-16 22:59:29,986] spring.jms.TestMessageListener - About to process message: Test Message!!  
 DEBUG: [Sep-16 22:59:29,986] spring.jms.TestMessageSender - About to put message on queue. Queue[queue://TestQueueTwo] Message[Test Message!!]  
 DEBUG: [Sep-16 22:59:30,022] spring.jms.TestMessageListener - Received message from queue [ActiveMQTextMessage {commandId = 99, responseRequired = false, messageId = ID:motown-58007-1347813056932-3:4:1:1:95, originalDestination = null, originalTransactionId = null, producerId = ID:motown-58007-1347813056932-3:4:1:1, destination = queue://TestQueueOne, transactionId = null, expiration = 0, timestamp = 1347832725483, arrival = 0, brokerInTime = 1347832725511, brokerOutTime = 1347832766192, correlationId = , replyTo = null, persistent = false, type = , priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@64b2aaa6, marshalledProperties = org.apache.activemq.util.ByteSequence@de1abf0, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = null}]  
 DEBUG: [Sep-16 22:59:30,022] spring.jms.TestMessageListener - About to process message: Test Message!!  
 DEBUG: [Sep-16 22:59:30,022] spring.jms.TestMessageSender - About to put message on queue. Queue[queue://TestQueueTwo] Message[Test Message!!]  
 DEBUG: [Sep-16 22:59:30,052] spring.jms.TestMessageListener - Received message from queue [ActiveMQTextMessage {commandId = 100, responseRequired = false, messageId = ID:motown-58007-1347813056932-3:4:1:1:96, originalDestination = null, originalTransactionId = null, producerId = ID:motown-58007-1347813056932-3:4:1:1, destination = queue://TestQueueOne, transactionId = null, expiration = 0, timestamp = 1347832725484, arrival = 0, brokerInTime = 1347832725511, brokerOutTime = 1347832766192, correlationId = , replyTo = null, persistent = false, type = , priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@5adf20ae, marshalledProperties = org.apache.activemq.util.ByteSequence@6edaae1d, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = null}]  
 DEBUG: [Sep-16 22:59:30,053] spring.jms.TestMessageListener - About to process message: Test Message!!  
 DEBUG: [Sep-16 22:59:30,053] spring.jms.TestMessageSender - About to put message on queue. Queue[queue://TestQueueTwo] Message[Test Message!!]
  • Now take a look at the number of messages on TestQueueTwo – it should now have 100 pending messages. These are the 100 messages that were consumed from TestQueueOne and pushed onto TestQueueTwo by our application. See screenshot below.

Figure 6.0 Messages pushed to TestQueueTwo

Wrapping Up

The sample code in this post should be enough to familiarise you with the fundamentals of JMS messaging with Spring. Although the code and sample configurations are very simple they should act as a basic guide and get you moving in the right direction. If you’re interested in learning more I’d recommend you look at the Spring documentation so that you can read up on some of the more advanced messaging features available. If you want to run this tutorial locally you can grab the full source code here https://docs.google.com/folder/d/0B_SZOyniHfc1YXE0M3BER242X28/edit Enjoy!
By |2019-02-20T17:16:58+00:00September 17th, 2012|JMS, Spring|61 Comments

61 Comments

  1. Brian 23rd September 2012 at 12:21 pm - Reply
  2. vjinaz 26th November 2012 at 9:03 pm - Reply

    Very nice explanation!

  3. jatin patel 17th December 2012 at 1:00 am - Reply

    Thank you soooooooooooooo much.

  4. Baldwinternet 23rd January 2013 at 5:35 am - Reply

    Why does the admin console show 2 consumers?

  5. Brian 23rd January 2013 at 9:06 am - Reply

    If you look at the configuration of the DefaultMessageListenerContainer in spring-config.xml you'll see that the concurrentConsumers property is set to 2. This means that Spring will create 2 invoker tasks to process incoming requests in an asynchronous fashion. So from the message brokers point of view there are 2 consumers.

  6. Asmita Sapkota 30th January 2013 at 8:07 pm - Reply

    This comment has been removed by the author.

  7. Asmita Sapkota 30th January 2013 at 8:14 pm - Reply

    Hi, I want to create a login page for activemq. I have downloaded the source code and tried creating login page but I am not able to do so.I would like users to login into the activemq page instead of just accessing it directly.It would be great if you share some ideas about how can i do that.
    Thanks

  8. fatih tekin 9th February 2013 at 10:08 pm - Reply

    hi relly good start for jms messaging but i suggest for new beginners using camel so all that configuration could be done easier

  9. Srinivas A 18th February 2013 at 3:27 am - Reply

    It is awesome explanation…keep on posting blogs.
    Thank You so much.

  10. Smrutiranjan Sahu 21st February 2013 at 11:25 am - Reply

    Thanks..:)

  11. Iris 19th April 2013 at 7:43 am - Reply

    Hi, can you define file pom.xml?

  12. Brian 19th April 2013 at 9:01 am - Reply

    The full source code including the POM file can be found here

  13. Iris 19th April 2013 at 11:50 am - Reply

    Very nice explanation! Thanks)

  14. Ayodeji Filegbe 20th April 2013 at 3:39 pm - Reply

    How do you run test this from within your project itself and not via the activeMQ admin console

  15. iris 24th April 2013 at 8:34 am - Reply

    You don't can to run this example via activeMQ admin console.
    You must install this application on application server (for example, apache tomcat).

  16. Gopal 25th April 2013 at 12:12 pm - Reply

    Thnx Nice explanation.

  17. Unknown 13th May 2013 at 10:00 am - Reply

    i tried as explained here everything works fine, but i get the error repeatedly on my tomcat 7.0.35 . This error goes off randomly

    13-05-2013 10:58:40 DEBUG AbstractInactivityMonitor:113 – WriteChecker 10001 ms elapsed since last write check.
    13-05-2013 10:58:40 DEBUG AbstractInactivityMonitor:156 – Running WriteCheck[tcp://127.0.0.1:61616]

  18. Clear 24th May 2013 at 4:35 am - Reply

    works fine. just couldn't find the log file.

  19. Dan 30th May 2013 at 4:14 pm - Reply

    Brian,

    Can you show the steps how to integrate tomcat here and how to run this from eclipse to get to see the console as shown above.

    Thanks,
    Dan

  20. Power Point Presentations 30th May 2013 at 4:25 pm - Reply

    This comment has been removed by a blog administrator.

  21. Brian 30th May 2013 at 4:31 pm - Reply

    You need to build the WAR file using Maven and deploy it to Tomcat the same way you would deploy any other WAR. Once the application is deployed, the DefaultMessageListenerContainer will start automatically and begin polling the ActiveMQ broker for messages. Once you add a new message through the ActiveMQ admin, the DefaultMessageListenerContainer should pick up the message and process it.

  22. Dan 30th May 2013 at 6:06 pm - Reply

    I am getting this exception while doing Maven install "
    C:devspring-activemq-samplesrcmainjavacomblogspringjmsTestMessageSender.java:[15,1] error: annotations are not supported in -source 1.3"

  23. Dan 30th May 2013 at 6:39 pm - Reply

    awesome thanks, I can now see these.

  24. Brian 30th May 2013 at 8:25 pm - Reply

    It looks like you're trying to build the WAR using a 1.3 jdk. It's complaining because you need Java 1.5 or greater to support annotations.

  25. Denis_B 20th June 2013 at 8:41 am - Reply

    You are the best!
    I see the Light now! ^_^
    The best, more complete and clear tutorial that i saw around!

  26. mohit jain 25th July 2013 at 7:30 am - Reply

    I am very thankful to you … for such a nice tutorial. but please can u tell me the steps also to deploy.. as i m not getting how to start this application…. i have done maven clean install and war file got created in target folder… please tell me after that what i have to do….

    one more query… when i have to start activemq.bat

    Hoping for a quick response…

    Once again thanks

  27. mohit jain 25th July 2013 at 7:49 am - Reply

    Hi Brian, i have figured out how to run this… thanks a lot for such a nice tutorial….

    It would be great if you include the brief explanation of xml Spring-Conf.xml file.. along with the use of same in Web application…

    Anyways appereciate your hard work…

  28. pensador 1st August 2013 at 3:53 pm - Reply

    Ive read it and its a very nice explanation, thanks

    But i have an issue, on eclipse which project should i create, cause i dont have that maven dependencies folder, if you could explain a little more the creation process it would be great.

    Thanks a lot

  29. Julien M 5th August 2013 at 2:30 pm - Reply

    Great presentation, used it at work and got great feedback so thank you. By the way had to change the priority tag in the log4j.xml file to 'debug' instead of 'info' for the debug messages to print out as shown in your screenshots. Thanks gain

  30. Brian 5th August 2013 at 2:39 pm - Reply

    All recent versions of Eclipse come with support for Maven. I'd highly recommend upgrading to one of these newer versions and importing as a Maven project. I use STS (Spring Tool Suite) – you can grab the latest from here. It has full Maven support out of the box.

  31. Brian 5th August 2013 at 2:39 pm - Reply

    Thanks Julien – glad you liked it.

  32. Julien M 6th August 2013 at 9:08 am - Reply

    Thanks Brian, I've also adapted it for topics but can't figure out how to make the listener persistent so that I don't have to be listening when I publish initial messages on the first topic and only pick the messages up when I start the program. Any idea how to achieve that?
    Also regarding the debug comment I made above I think the correct thing to do is instead to leave the leave the priority tag as 'info' and change the logger_c.debug in the two classes to logger_c.info

  33. Jonathan Melian 6th August 2013 at 2:35 pm - Reply

    Could you tell me how did you run it? cause i am not able to do it

    Thanks

  34. Brian 6th August 2013 at 3:07 pm - Reply

    The listener itself is not persistent. Its job is to poll the message broker (Active MQ in this instance) for new messages, retrieve those message from the queue and process them. The message broker can be configured for JDBC persistence so that messages held by the broker will persisted between restarts. See the Active MQ documentation for more information on JDBC persistence configuration.

  35. Jonathan Melian 6th August 2013 at 9:32 pm - Reply

    This comment has been removed by the author.

  36. Jonathan Melian 6th August 2013 at 9:32 pm - Reply

    This comment has been removed by the author.

  37. Brian 7th August 2013 at 6:39 am - Reply

    There is no main method to run the sample code. You need to build the sample application as a WAR file and deploy it to a Servlet container. On application startup it will connect to the message broker (Active MQ) and start polling the message queue that was configured in context.xml. When a new message is put on the queue the application will consume that message and process it.

  38. The Java Codeslinger 8th August 2013 at 6:55 pm - Reply

    For those of us like myself, that need a little more detailed explanation of how to run this application:

    – All the following steps assume you are using a recent version of Eclipse with Maven support. If not, you are on your own!
    – Do a Maven Clean and Maven Install on the .pom file Brian provided in the download. If you get a clean build, this will create and deploy your WAR file.
    – On your Eclipse Servers tab:
    – Click on server
    – Chose Add deployment
    – Drop down list should include the project (spring-activemq-sample)
    – Click Finish
    – Start Tomcat

    – Start ApacheMQ as Brian described in the tutorial
    – Set up ActiveMQ Administration console as also described
    – Configure the console to send your message as also described.
    – Click Send
    – The messages will display on your Eclipse console (Console tab in Eclipse)

  39. Ayodeji Filegbe 8th August 2013 at 7:46 pm - Reply

    Please how would you from within your application instead of through the admin console create a message that would be sent. Great tutorial by the way.

  40. Chienhao Huang 17th September 2013 at 11:40 pm - Reply

    Excellent blog…
    but, I am confused in running the application. could you advice me how to run the application in eclipse? I have started activemq and put message into queue, but, I don't have ideal to start the application in clipse.

  41. VickyFlyer 15th October 2013 at 12:04 pm - Reply

    You know you just saved my Job Today, and made me more firm in making this type of help ful material for other programmers too… (y)

  42. VickyFlyer 15th October 2013 at 12:07 pm - Reply

    I think its more easir for you to run it on tomcat alone, If you have maven installed (in eclipse) then Run a 'clean install' by clicking on project and going to maven menu… after that you will find a newly made war file in target folder copy it to webapps in tomcat and run tomcat ….

    Hope it helps.

  43. shorav 31st October 2013 at 6:53 am - Reply

    Hi Brian,I am a die hard follower of your tutorial and I lerant a lot from video and articles. Here I have a situation to implement middleware in my project.

    Existing system:
    I have a Restful service API developed with JAX-RS and jersey. I have deployed the same in TOMCAT 7. Now I would like to implement Active Mq so that I would keep all request in a queue and process the api. How to do this and integrate with tomcat7. From this article; I would be able to integrate ActiveMq with Tomcat7. but how to call the service.

    Please gide me. I am in great need of your guidence.

    Thanks
    Kumar Shorav

  44. kheir kheir 1st April 2014 at 4:24 pm - Reply

    THX VERY MUCH BRIAN….

  45. raj gopal 28th May 2014 at 5:57 am - Reply

    Hi Brians…
    Thanks for the blog…can u please tell me how to connect to IBM mq??
    what all to change in context.xml?

  46. Sandy 12th September 2014 at 10:01 pm - Reply

    Thanks a lot for posting such a nice tutorial..

  47. Ballu Ashok 20th September 2014 at 6:02 am - Reply

    Thanks Brian, can you please also guide us on integrating with IBM MQ series instead of Active MQ

  48. Kat 16th October 2014 at 10:44 am - Reply

    Hey Brian!

    Thanks for the detailed tutorial, this was very helpful! Just had a query though, WHat do we have to do to prevent a message from getting dequeued in the onMessage method if we want to do so in case of an exception ?

    Would be great if you could shed some light on the same 🙂

  49. Kat 16th October 2014 at 10:50 am - Reply

    Ok I think I got the answer on my own, we just need to throw an exception!

    Thanks once again!

  50. Mr.Chowdary 12th November 2014 at 9:19 am - Reply

    I thought this would be working for Jboss EAP 6.2 as well.. Ooops.. but not working.. it's not able to find the mqConnectionFactory object. I followed the following tutorial to configure ActiveMQ as adapter https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.1/html/Deploying_into_a_Web_Server/files/DeployRar-InstallRar.html.
    Brian should have mentioned this works only for Tomcat. Any how i realized and it took a many hours to find out.
    Hope this helps for who looks for activemq as adapter for Jboss

  51. Ramu Gadde 1st March 2015 at 7:27 am - Reply

    Hi Brian,we need normal tomcat-7 or TomEE-7

  52. Nikunj 18th May 2015 at 6:46 pm - Reply

    Nice Tutorial !!!

  53. Nikunj 18th May 2015 at 6:46 pm - Reply

    Nice Tutorial !!!

  54. Nikunj 18th May 2015 at 6:46 pm - Reply

    Nice Tutorial !!!

  55. Sachit Khanna 16th August 2015 at 8:55 pm - Reply

    Thanks @The Java Codeslinger

  56. Sachit Khanna 16th August 2015 at 9:24 pm - Reply

    Thanks @The Java Codeslinger

  57. Sana 11th November 2015 at 10:59 pm - Reply

    Hi Brian,
    I am getting this error on running it on Tomcat Server within Eclipse
    2015-11-11 23:42:15,423 | WARN | ultMessageListenerContainer | Could not refresh JMS Connection for destination 'queue://TestQueue1' – retrying in 5000 ms. Cause: Could not create Transport. Reason: java.io.IOException: Transport scheme NOT recognized: [tcp]

  58. Kristi Byrd 28th January 2016 at 6:16 am - Reply

    Grateful to check out your website, I seem to be ahead to more excellent content and I believe we all really like to thank for so many excellent content, weblog to discuss with us CRM Nimble

  59. Jeanne Davies 31st March 2016 at 8:02 am - Reply

    Nice list of ideas that can help to improve our website designing, when i designing website I will remember these points and make some good designing.Android Applications Development

  60. Unknown 28th April 2016 at 5:13 pm - Reply

    Brian, Thanks for a wonderful example oriented tutorial. So nice. Stuff like this are very scarce in www. Very nice for a beginner

  61. DIMAS TRI APRIYANTO 26th September 2016 at 3:57 pm - Reply

    god bless you

Leave A Comment