Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Integrating with ActiveMQ

For using ActiveMQ queues and topics with Jetty, you have two choices:

  1. Use queues and topics directly from javascript on the client browser (Ajax)
  2. Traditional server-side jms api calls

ActiveMQ with Ajax and Jetty

Due to some clever integration, you can use queues and topics directly in your client side javascript very easily and simply.

Here's an example of sending a message to a queue:

Code Block
 amq.sendMessage('channel://MY.DEMO', "<message item='hello'/>");

Here's an example of setting up to receive messages from a queue. All you need do is to add a listener with a unique id, the name of the queue or topic from which you want to receive messages, and the name of a function which will be called back when a message is available.

Code Block

var myHandler = 
{  
  rcvMessage: function(message) 
  {
     alert("received "+message);
  }
};

 amq.addListener(myId, 'channel://MY.DEMO', myHandler.rcvMessage);

Here's the plumbing you need to take advantage of this very convenient feature:

  • Include these lines in your html:
No Format
    <script type="text/javascript" src="amq/amq.js"></script>
    <script type="text/javascript">amq.uri='amq';</script>
  • Include thse lines in your web.xml, changing the url of the broker as appropriate for your installation:
No Format
    <context-param>
        <param-name>org.apache.activemq.brokerURL</param-name>
        <param-value>vm://localhost</param-value>
        <description>The URL of the Message Broker to connect to</description>
    </context-param>

    <context-param>
        <param-name>org.apache.activemq.embeddedBroker</param-name>
        <param-value>true</param-value>
        <description>Whether we should include an embedded broker or not</description>
    </context-param>

    <servlet>
      <servlet-name>AjaxServlet</servlet-name>
      <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>AjaxServlet</servlet-name>
        <url-pattern>/amq/*</url-pattern>
    </servlet-mapping>

    <filter>
      <filter-name>session</filter-name>
      <filter-class>org.apache.activemq.web.SessionFilter</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>session</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

  • Include the activemq-web.jar and all of its dependencies in your webapp, or alternatively, copy them to the $JETTY-HOME/lib/ext directory if you want them to be available for all of your webapps. Here's a maven2 dependency clause that you might find useful:
No Format
    <dependency>
      <groupId>incubator-activemq</groupId>
      <artifactId>activemq-web</artifactId>
      <exclusions>
        <exclusion>
          <artifactId>commons-logging</artifactId>
          <groupId>commons-logging</groupId>
        </exclusion>
        <exclusion>
          <artifactId>org.mortbay.jetty</artifactId>
          <groupId>jetty-util</groupId>
        </exclusion>
        <exclusion>
          <artifactId>mx4j</artifactId>
          <groupId>mx4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>

You will also need to make sure that jcl104-over-slf4j-1.0.1.jar and an slf4j log implementation jar are available at runtime, as ActiveMQ uses commons logging. You can move these jars out of $JETTY-HOME/lib/jsp-2.0 and into $JETTY-HOME/lib to make them generally available on the classpath.

This ActiveMQ Ajax mechanism is based on Jetty's Continuations mechanism and thus in fact works most efficiently when deployed on Jetty, however the same webapp will also run unaltered on other containers.

There is more information on available on ActiveMQ in general and the Ajax mechanism in particular.

ActiveMQ with JNDI lookups from Servlets

You can use ActiveMQ queues and topics in the traditional manner from Servlet code with Jetty. Firstly, if you are not familiar with how JNDI resources are configured with Jetty, take a look at the JNDI Feature page.

Now lets look at the steps you need to perform to be able to access queues and topics:

  • Copy all of the activemq jars and their dependent jars into $JETTY-HOME/lib/ext/activemq.
  • Make sure that you have jcl104-over-slf4j-1.0.1.jar and an slf4j log implementation jar available on the classpath. These jars are available in $JETTY-HOME/lib/jsp-2.0, but if you are not using jsp-2.0, you'll need to move them out of there and either up one level into $JETTY-HOME/lib or down into $JETTY-HOME/lib/ext/activemq.
  • Edit the $JETTY-HOME/etc/jetty-plus.xml file and define your connection factories and any queues or topics that you want to be available in a JNDI lookup from any webapp. If you want to make any of these resources scoped to a single webapp, then put the setup instead into a jetty-env.xml file and put it in your webapps WEB-INF/ directory. Here's an example of a QueueConnectionFactory, change the broker url to be appropriate for your setup:
Code Block
xml
xml
<New id="cf" class="org.mortbay.jetty.plus.naming.Resource">
  <Arg>jms/connectionFactory</Arg>
  <Arg>
    <New class="org.apache.activemq.ActiveMQConnectionFactory">
       <Arg>vm://localhost?broker.persistent=false</Arg>
    </New>
  </Arg>
</New>

Here's an example of a Queue:

Code Block
xml
xml
<New id="myQueue"  class="org.mortbay.jetty.plus.naming.Resource">
  <Arg>jms/myQueue</Arg>
  <Arg>
    <New class="org.apache.activemq.command.ActiveMQQueue">
      <Arg>DEMO</Arg>
    </New>
  </Arg>
</New>
  • Edit your WEB-INF/web.xml file for your webapp to link up to the resources you defined in the step above. Following our example ConnectionFactory and Queue, we'd add:
Code Block
xml
xml
<!-- JMS  connection factory ref -->
<resource-ref>
  <description>Connection Factory</description>
  <res-ref-name>jms/connectionFactory</res-ref-name>
  <res-type>javax.jms.QueueConnectionFactory</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

<!-- Queue ref -->
<resource-env-ref>
  <resource-env-ref-name>jms/myQueue</resource-env-ref-name>
  <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
  • Code your servlet to use JNDI lookups to access and operate on these resources. For example, here's the code snippets to put a message onto a queue (these full example is MyQueueServlet.java):
Code Block

    private QueueConnectionFactory connectionFactory;
    private Queue myQueue;

    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
        try
        {
            InitialContext ic = new InitialContext();
            connectionFactory = (QueueConnectionFactory)ic.lookup("java:comp/env/jms/connectionFactory");
            myQueue = (Queue)ic.lookup("java:comp/env/jms/myQueue");
        }
        catch (Exception e)
        {
          e.printStackTrace();
            throw new ServletException(e);
        }
    }
.
.
.
    public void sendMessage(String msg)
    throws Exception
    {
        QueueConnection connection = null;
        QueueSession session = null;
        MessageProducer producer = null;
        try
        {
          connection = connectionFactory.createQueueConnection();
          session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          producer = session.createProducer(myQueue);
          TextMessage message = session.createTextMessage(msg);
          producer.send(message);
        }
        finally
        {
          try
          {
            if (producer!=null)producer.close();
            if (session!=null)session.close();
            if (connection!=null)connection.close();
          }
          catch (Exception e)
          {
            e.printStackTrace();
          }
        }
    }
  • Now deploy your webapp to $JETTY-HOME/webapps-plus
  • Run it with:
Code Block
java -jar start.jar etc/jetty.xml etc/jetty-plus.xml

You're done!

Contact the core Jetty developers at www.webtide.com
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery