Ejb3 Basics: Deploying Message Driven Beans

Farewell to lazy auto queue generation in JBoss 5

MDB’s were never so easy to deploy and manage when ejb3 first came out. In Jboss 4, all you have to do was annotate a class with @MessageDriven, sprinkle some meta data here and there, stick it in the oven and wham! Instant “I cant believe I made an MDB!?!” In Jboss AS 5 however, MDB queues are no longer automatically created for your application anymore on boot. An inspection of the MDB llifecycle illustrates why:

  1. MDB deploys
  2. No existing Topic/Queue
  3. Topic/Queue is automatically created
  4. MDB is undeployed
  5. There’s no callback/hook to remove the created Topic/Queue. And if there was, should undeploying the MDB even be allowed to trigger this action?

blatantly stolen from JBAS-5114, 5th comment down – thanks Andy, and DeCoste by proxy

SO to reiterate… whereas JBoss AS 4.0 would have auto-created and MDB queues for you on boot, in 5.0 this no longer holds true. Consider the following MDB:

package com.examples.mdb;

import javax.ejb.*;
import javax.jms.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

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

	private static final Log log = LogFactory.getLog(MyQueue.class);

	public void onMessage (Message msg) {
		try {

			log.debug("Processing MyQueue queue...");
			ObjectMessage oMsg = (ObjectMessage) msg;

			SomeObject result = (SomeObject ) oMsg.getObject();

			/**
			 * do stuff with the object
			 */

		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

In jboss 4 you could leave your MDB class like this, and the app server would automatically handle everything for you. If you plan on using jboss 5.+ however, you will have to choose one of the following..

Wire it yourself in destinations-service.xml

In /deploy/messaging/destinations-service.xml, you can add the MDB destination yourself, letting jboss know to create your queue on boot. Here’s an example configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!--
	Messaging Destinations deployment descriptor.
 -->
<server>

	<mbean
		code="org.jboss.jms.server.destination.QueueService"
		name="jboss.messaging.destination:service=Queue,name=MyQueue"
		xmbean-dd="xmdesc/Queue-xmbean.xml">
		<depends optional-attribute-name="ServerPeer">
			jboss.messaging:service=ServerPeer
		</depends>
		<depends>
			jboss.messaging:service=PostOffice
		</depends>
	</mbean>

</server>

The only thing this configuration needs to change is the queue name – make sure it matches the name of the queue annotated in your MDB class. This by itself is the closest you can get to being lazy. You will need to make sure however that you add one destination for each of the MDB queues your application uses. Option two requires a little bit more work but you don’t have to muck around with the jboss environment…

Add deployment descriptors to auto create the queue via jboss.xml

You can instead deploy the optional jboss.xml file in your ejb jar file’s META-INF folder (in addition to your persistence.xml file if you’re using entities). Your ejb jar structure should then look like this:

ejb-jar.jar
	- / ejb classes and cool stuff here
	- / META-INF
		- MANIFEST.MF
		- persistence.xml
		- jboss.xml

And this is what jboss.xml would look like:

<?xml version="1.0" encoding="UTF-8"?>
<jboss xmlns="http://www.jboss.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee
                           http://www.jboss.org/j2ee/schema/jboss_5_0.xsd"
       version="3.0">
	<enterprise-beans>
		<message-driven>
			<ejb-name>MyQueue</ejb-name>
			<destination-jndi-name>queue/MyQueue</destination-jndi-name>
			<create-destination>true</create-destination>
		</message-driven>
	</enterprise-beans>
</jboss>

The key command in this file here being: <create-destination>true</create-destination>. This will flag jboss to create the queue for you if it doesn’t already exist. This approach would probably be better suited for jboss only deployments since the flag to auto create the queue is configured within a jboss exclusive deployment descriptor – jboss.xml.

Once either of these has been implemented, your MDB should be deployed, initialized and ready to fire up. Oh, and fist pumps to ALR for pointing me in the right direction – cheers buddy!



 
  • Twitter
  • del.icio.us
  • Reddit
  • Technorati
  • Google Bookmarks
  • Blogplay
  • Yahoo! Buzz
  • LinkedIn
  • Facebook

Related posts:

  1. Ejb3 Basics: Bean Managed Transactions
  2. Ejb3 basics: Entities
  3. War deployment file structure
Posted on February 2, 2010 at 12:37 am by Ant · Permalink
In: Java, Jboss · Tagged with: , , , , , ,

Leave a Reply