3

I am new to JEE7 and have been working on some quick exercises but I've bumped into a problem. I have a sample Java SE application that sends a message to an ActiveMQ queue and I have an MDB deployed on Wildfly 8 that reads the messages as they come in. This all works fine and I can receive the messages using getText. However, when I use getBody to get the message body, I get an "Unknown Error". Can anyone let me know what I'm doing wrong?

Here's my code below;

/***CLIENT CODE****/
    import javax.jms.*;
    import org.apache.activemq.ActiveMQConnection;
    import org.apache.activemq.ActiveMQConnectionFactory;

    public class SimpleMessageClient {
        // URL of the JMS server. DEFAULT_BROKER_URL will just mean
        // that JMS server is on localhost
        private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;

        // Name of the queue we will be sending messages to
        private static String subject = "MyQueue";

        public static void main(String[] args) throws JMSException {
            // Getting JMS connection from the server and starting it
            ConnectionFactory connectionFactory =
                new ActiveMQConnectionFactory(url);
            Connection connection = connectionFactory.createConnection();
            connection.start();

            // JMS messages are sent and received using a Session. We will
            // create here a non-transactional session object. If you want
            // to use transactions you should set the first parameter to 'true'
            Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

            // Destination represents here our queue 'TESTQUEUE' on the
            // JMS server. You don't have to do anything special on the
            // server to create it, it will be created automatically.
            Destination destination = session.createQueue(subject);

            // MessageProducer is used for sending messages (as opposed
            // to MessageConsumer which is used for receiving them)
            MessageProducer producer = session.createProducer(destination);

            // We will send a small text message saying 'Hello' in Japanese
            TextMessage message = session.createTextMessage("Jai Hind");

            //Message someMsg=session.createMessage();
           // someMsg.

            // Here we are sending the message!
            producer.send(message);
            System.out.println("Sent message '" + message.getText() + "'");

            connection.close();
        }
    }

And the consumer;

    package javaeetutorial.simplemessage.ejb;

    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.annotation.Resource;
    import javax.ejb.ActivationConfigProperty;
    import javax.ejb.MessageDriven;
    import javax.ejb.MessageDrivenContext;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageListener;
    import javax.jms.TextMessage;


    @MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "MyQueue")
    })
    public class SimpleMessageBean implements MessageListener {

        @Resource
        private MessageDrivenContext mdc;
        static final Logger logger = Logger.getLogger("SimpleMessageBean");

        public SimpleMessageBean() {
        }

        @Override
        public void onMessage(Message inMessage) {
            try {            
if (inMessage instanceof TextMessage) {
                logger.log(Level.INFO,
                        "MESSAGE BEAN: Message received: {0}",
                        inMessage.getBody(String.class));
            } else {
                logger.log(Level.WARNING,
                        "Message of wrong type: {0}",
                        inMessage.getClass().getName());
            }
            } catch (JMSException e) {
                e.printStackTrace();
                logger.log(Level.SEVERE,
                        "SimpleMessageBean.onMessage: JMSException: {0}",
                        e.toString());
                mdc.setRollbackOnly();
            }
        }
    }

Part of the error I get is;

16:47:48,510 ERROR [org.jboss.as.ejb3] (default-threads - 32) javax.ejb.EJBTransactionRolledbackException: Unexpected Error
16:47:48,511 ERROR [org.jboss.as.ejb3.invocation] (default-threads - 32) JBAS014134: EJB Invocation failed on component SimpleMessageBean for method public void javaeetutorial.simplemessage.ejb.SimpleMessageBean.onMessage(javax.jms.Message): javax.ejb.EJBTransactionRolledbackException: Unexpected Error
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:157) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:253) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:342) [wildfly-ejb3-8.2.0.Final.jar:8.2.0.Final]
amusingalan
  • 35
  • 1
  • 5

1 Answers1

4

The method

<T> T Message.getBody(Class<T> c)

you refer to was an addition to JMS 2.0 (see also: http://www.oracle.com/technetwork/articles/java/jms20-1947669.html).

While WildFly 8 is fully compliant to Java EE 7 and therefore JMS 2.1, the current ActiveMQ (5.12.0) is still restricted to JMS 1.1.

Since you presumably import the JMS 2.1 API in your SimpleMessageBean, you reference a method simply not present in the ActiveMQ message.

When you try to call the getBody()-method on the message, it cannot be resolved in the message implementation and hence an AbstractMethodError is thrown. This results in the rollback of the transaction which gives you the EJBTransactionRolledbackException.

I see two immediate solutions for your problem:

  1. If you want to keep using ActiveMQ, confine yourself to the JMS 1.1 API. The getText()-method you mentioned is part of JMS 1.1 and therefore works flawlessly. See here for the JMS 1.1 API (https://docs.oracle.com/javaee/6/api/javax/jms/package-summary.html) and here for the current ActiveMQ API documentation (http://activemq.apache.org/maven/5.12.0/apidocs/index.html).

  2. Switch to a JMS 2.x compliant message broker. Since you are using WildFly, I recommend taking a look at HornetQ (http://hornetq.jboss.org/).

vlow
  • 171
  • 6