Friday, October 26, 2012

Using a Message-Driven Bean in JBoss 7

Let me describe the environment where this example runs: I assume that we will deploy a EJB in JBoss 7, and this JBoss includes an implementation of a queueing system accessible via Java Message Service. Additionally, I assumes that we already configured a queue named queue/PlayQueue. Refer to my other message about the Java Message Service for details on how to configure such queue. Again, we need to start JBoss in the following way, to start the messaging system:


./standalone.sh --server-config=standalone-full.xml



We now can write the code of the Message Bean. It is actually quite simple. Pick the Java EE perspective on the upper right corner of Eclipse. Then, create a new EJB Project (File-->New menu). Here I only show the source code of the bean in a Java package named message. The most important and not-so-obvious details concern the annotation @MessageDriven:



package message;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

/**
 * Message-Driven Bean implementation class for: MyBean
 *
 */
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/PlayQueue")
},
mappedName = "queue/PlayQueue")
public class MyBean implements MessageListener {

    /**
     * Default constructor. 
     */
    public MyBean() {
    }
/**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message message) {
    try {
System.out.println("Recebi: " + ((TextMessage) message).getText());
} catch (JMSException e) {
e.printStackTrace();
}
    }

}

To export the project to JBoss we do as usual:

The project in the form of a .jar file goes to standalone/deployments directory of JBoss:

You can now check the output of JBoss to see if everything went smoothly.

And now we need a program to send a message:


import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.NamingException;


import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.jms.HornetQJMSClient;
import org.hornetq.api.jms.JMSFactoryType;
import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;


public class Sender {
private ConnectionFactory cf;
private Connection c;
private Session s;
private Destination d;
private MessageProducer mp;

public Sender() throws NamingException, JMSException {
TransportConfiguration transportConfiguration =
new TransportConfiguration(NettyConnectorFactory.class.getName());              
cf = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,transportConfiguration);
c = cf.createConnection("joao", "pedro");
d = HornetQJMSClient.createQueue("PlayQueue");

this.s = this.c.createSession(false, Session.AUTO_ACKNOWLEDGE);
this.c.start();
this.mp = this.s.createProducer(this.d);
}

public void send(String contents) throws JMSException {
TextMessage m = this.s.createTextMessage();
m.setText(contents);
this.mp.send(m);
}

public void close() throws JMSException {
this.c.close();
}
public static void main(String[] args) throws NamingException, JMSException {
Sender s = new Sender();
s.send("Ola");
}

}

Once you execute this code you should get the following view or similar in JBoss' console: