One thing that’s missing from the Duke’s Bank application is any use of JMS messaging, so we’ll work through the tutorial example on Message Driven Beans (MDBs) to see how to use messaging in JBoss. We’ll assume you’re already familiar with general JMS and MDB concepts. The J2EE tutorial code for the MDB is in j2eetutorial14/examples/ejb/simplemessage. We’ve supplied a jboss-build.xml file in the simplemessage directory which will allow you to build the example from scratch and run it in JBoss.
The example code is very simple. There are only two classes, one for the client and one for the bean (unlike normal EJBs, MDBs don’t need any interfaces). The client publishes messages to a JMS Queue and the MDB handles them via its standard onMessage method. The messages are all of type javax.jms.TextMessage and the bean simply prints out the text contained in each message.
The only container-specific tasks required are setting up the Queue in JBoss, and configuring the MDB to accept messages from it.
To compile the files, invoke the compile-mdb target from the simplemessage directory.
ant -f jboss-build.xml compile-mdb
Then run the following targets to produce archives for the bean and the client and a combined EAR file in the jar directory.
ant -f jboss-build.xml package-mdb ant -f jboss-build.xml package-mdb-client ant -f jboss-build.xml assemble-mdb
We’ve retained the same layout we used in the Duke’s Bank build, with a dd directory containing the deployment descriptors and the jar directory containing the archives produced by the build.
As with other container-specific information, the queue name for the MDB is specified in the jboss.xml file:
<jboss> <enterprise-beans> <message-driven> <ejb-name>SimpleMessageBean</ejb-name> <destination-jndi-name>queue/MyQueue</destination-jndi-name> </message-driven> </enterprise-beans> </jboss>
The MDB will receive messages from the queue with JNDI name queue/MyQueue.
To deploy the MDB, copy the SimpleMessage.ear file to the JBoss deploy directory. The deploy-mdb target does this:
ant -f jboss-build.xml deploy-mdb
A successful deployment should look something like this:
14:19:17,211 INFO [EARDeployer] Init J2EE application: file:/private/tmp/jboss-4.0.2/server/default/deploy/SimpleMessage.ear 14:19:18,596 INFO [EjbModule] Deploying SimpleMessageEJB 14:19:19,671 WARN [JMSContainerInvoker] Could not find the queue destination- jndi-name=queue/MyQueue 14:19:19,813 WARN [JMSContainerInvoker] destination not found: queue/MyQueue reason: javax.naming.NameNotFoundException: MyQueue not bound 14:19:19,813 WARN [JMSContainerInvoker] creating a new temporary destination: queue/MyQueue 14:19:20,012 INFO [MyQueue] Bound to JNDI name: queue/MyQueue 14:19:21,042 INFO [EJBDeployer] Deployed: file:/private/tmp/jboss-4.0.2/server/def ault/tmp/deploy/tmp50656SimpleMessage.ear-contents/simplemessage.jar 14:19:21,223 INFO [EARDeployer] Started J2EE application: file:/private/tmp/jboss- 4.0.2/server/default/deploy/SimpleMessage.ear
If you look more closely at this, you will see warnings that the message queue specified in the deployment doesn’t exist. In this case JBoss will create a temporary one for the application and bind it under the supplied name. You can check it exists using the JNDIView MBean again. Look under the global JNDI namespace. We’ll look at how to explicitly create JMS destinations below.
Run the client with the run-mdb Ant target.
ant -f jboss-build.xml run-mdb
You should see output in both the client and server windows as they send and receive the messages respectively.
As with most things in JBoss, JMS Topics and Queues are implemented using MBeans. There are two ways you can create them: you can add MBean declarations to the appropriate configuration file, or you can create them dynamically using the JMX Console. However, if you use the latter method, they won’t survive a server restart.
You’ll find this file in the jms directory inside the deploy directory. It contains a list of JMS destinations and sets up a list of test topics and queues which illustrate the syntax used. To add the queue for our example, you would simply add the following MBean declaration to the file.
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=MyQueue"> </mbean>
With JBoss running, bring up the JMX Console in your browser and look for the section labelled jboss.mq in the main agent view. Click on the link which says service=DestinationManager. The DestinationManager MBean is the main JMS service in JBoss and you can use it to create and destroy queues and topics at runtime. Look for the operation called createQueue. There will be two operations by that name, both of which take a different number of arguments. Look for the one that takes only one argument. That argument is the name of the queue. This takes two parameters. Enter MyQueue and click the Invoke button. This will create a queue bound under the JNDI name queue/MyQueue, assuming it doesn't already exist.
You can access the attributes and operations that the MBeans representing a queue or topic exposes via JMX. Look at the main JMX Console view again and you’ll find a separate jboss.mq.destination section which should contain an entry for our Queue (no matter how it was created). Click on this and you’ll see the attributes for the queue. One of them is QueueDepth, which is the number of messages which are currently on the queue.
As an exercise, you can try temporarily stopping the delivery of messages to the MDB. Locate the section called jboss.j2ee in the JMX console and you should find an MBean listed there which is responsible for invoking your MDB. The name will be binding=message-driven-bean, jndiName=local/SimpleMessageEJB, plugin=invoker,service=EJB
You can start and stop the delivery of messages using the corresponding MBean operations which it supports. Invoke the stopDelivery() method, and then run the client a few times. You will see the QueueDepth increase as the messages accumulate. If you re-start message delivery, with the startDelivery() method, you should see all the messages arriving at once.