I was about to compare Message Driven Beans (MDB) with Spring JMS and started to setup a small application with an MDB and a servlet. Messages should be sent from the servlet to a ActiveMQ queue and the MDB should then receive them. The application was to be deployed on Glassfish v3 ( I ran into a few problems which I will document for you to find in this blog post.

First I created my application using the built-in JMS broker shipped with Glassfish v3 (OpenMQ). This was quite straight forward and worked nicely.

Then I downloaded ActiveMq 5.7.0 and started a broker from the installation dir:

  1. bin/activemq start
  2. Tail log: tail -f data/activemq.log
  3. Load admin console: http://localhost:8161/admin/

To switch over to ActiveMQ as a JMS broker, I followed the steps described in this post by Geert Shuring. Versions are updated to current of today:

  1. Copy the following jars from ActiveMQ lib and lib/optional folders to the Glassfish lib folder: slf4j-api-1.6.6.jar, slf4j-log4j12-1.6.6.jar and log4j-1.2.17.jar.
  2. Download activemq-rar-5.7.0.rar from here and install as a Resource adapter using Glassfish admin console (http://localhost:4848/). (Application type is automatically detected by Glassfish)
  3. Create a new config, using Glassfish admin console, under Resources -> Resource adapter configs:
    • Resource adapter name = activemq-rar-5.7.0
    • Thread pool id = thread-pool-1
    • Additional properties untouched! (defaultUser / defaultPassword / tcp://localhost:61616 etc)
  4. Create a new Connector connection pool using admin console under Resources -> Connectors -> Connector Connection Pools with:
    • Pool name = amqpool
    • Resource adapter = activemq-rar-5.7.0
    • Connection definition = javax.jms.ConnectionFactory
  5. Create a new Connector Resource using admin console under Resources -> Connectors -> Connector Resources with:
    • JNDI name = amqres
    • Pool name = amqpool
  6. Create a new Admin Object Resource using asadmin tool. Don’t create the resource from the admin console! It caused me problems where the resource could not be found using JNDI. (This is most likely a bug in the admin console.)
    • Start asadmin from Glassfish bin folder
    • Execute command create-admin-object –restype javax.jms.Queue –raname activemq-rar-5.7.0 –property PhysicalName=incomingAmq incomingAmq
    • Check the new resource in the admin console
  7. Now the Glassfish configurations should be ready.

You can check the Connector Connection Pool being connected to ActiveMQ by clicking Ping button on the amqpool object.

After the configurations are ready, it’s time to write some code. These are the important files for the application:


package dag;

import javax.annotation.Resource;
import javax.jms.*;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SendServlet extends HttpServlet {
@Resource(mappedName = "amqres")
private ConnectionFactory connectionFactory;

@Resource(mappedName = "incomingAmq")
private Queue incoming;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String messageText = request.getParameter("x");
  ServletOutputStream out = response.getOutputStream();
  out.println("<p>ConnectionFactory: "+connectionFactory+"</p>");
  out.println("<p>Queue: "+ incoming + "</p>");
  out.println("<p>Servlet sending '"+messageText+"' to queue.</p>");

  Connection connection;
  try {
    connection = connectionFactory.createConnection();
    Session session = connection.createSession(false,
    MessageProducer messageProducer = session.createProducer(incoming);
    TextMessage message = session.createTextMessage();
  } catch (JMSException e) {
    throw new RuntimeException(e);
  out.println("Done sneding.");


package dag;

import javax.ejb.*;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

  activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "incomingAmq")
public class MessageReceiverBean implements MessageListener {
  public MessageReceiverBean() {

  public void onMessage(Message message) {
    try {
      System.out.println("Received: "+((TextMessage)message).getText());
    } catch (JMSException e) {
      throw new RuntimeException(e);


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">

(ejb-jar.xml should not be needed)

Create an ear package and deploy to Glassfish. Go to http://localhost:8080/web/servlet?x=theOatmeal to test the application. What is given in request parameter x should be sent to the JMS queue ‘incomingAmq’ and the MDB should then receive this message from ‘incomingAmq’ and print it on stdout. The physical queue ‘incomingAmq’ will be automatically created by ActiveMQ. Take a look at the AMQ admin console: http://localhost:8161/admin/queues.jsp

Possible problems that may occur:

  • When invoking the SenderServlet you get an error in the log like “javax.naming.NameNotFoundException: incomingAmq not found”, where “incomingAmq” is the resource mappedName in the SernderServlet. This may be caused by creating the Admin Resource Object “incomingAmq” from the admin console. Create it using asadmin as described above! Stacktrace may look like:
javax.naming.NameNotFoundException: incomingAmq not found
	at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
	at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
	at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
	at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
	at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
	at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
	at javax.naming.InitialContext.lookup(InitialContext.java:392)
  • If you get the following NullPointerException when invoking the servlet, you may be missing the PhysicalName property on the Admin Resource object ‘incomingAmq’. It should be included in the object if created using the asadmin command above. Otherwise you can add the property using the admin console.
	at org.apache.activemq.command.ActiveMQDestination.hashCode(ActiveMQDestination.java:329)
	at java.util.HashMap.get(HashMap.java:300)
	at org.apache.activemq.openwire.OpenWireFormat.getMarshallCacheIndex(OpenWireFormat.java:517)
	at org.apache.activemq.openwire.v9.BaseDataStreamMarshaller.tightMarshalCachedObject1(BaseDataStreamMarshaller.java:158)
	at org.apache.activemq.openwire.v9.ProducerInfoMarshaller.tightMarshal1(ProducerInfoMarshaller.java:98)
	at org.apache.activemq.openwire.OpenWireFormat.marshal(OpenWireFormat.java:234)
	at org.apache.activemq.transport.tcp.TcpTransport.oneway(TcpTransport.java:183)