Let's now develop a simple message-driven EJB to receive text messages from a JMS queue and print the messages to the server's stderr.
The MessageDrivenBean class includes the four required methods. The onMessage method receives the JMS message and prints the associated text. For this simple example, any error is simply printed to the server's stderr.
package com.learnweblogic.examples.ch10.textmessage; import javax.ejb.MessageDrivenBean; import javax.ejb.MessageDrivenContext; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; public class MessagePrinterBean implements MessageDrivenBean, MessageListener { private MessageDrivenContext ctx; public void setMessageDrivenContext( MessageDrivenContext c) { ctx = c; } public void ejbCreate() {} public void ejbRemove() {} public void onMessage(Message m) { TextMessage msg = (TextMessage) m; try { System.err.println( "Message-Driven EJB received message: "+ msg.getText()); } catch (JMSException e) { System.err.println( "Exception receiving text from message: "); e.printStackTrace(); } } }
Like other EJBs, message-driven EJBs require an ejb-jar.xml deployment descriptor. This descriptor includes the name of the bean class, the transaction type, and the JMS destination. Like session beans, message-driven EJBs may use either bean or container transaction attributes. We discuss the different transaction settings later in this chapter
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <enterprise-beans> <message-driven> <ejb-name>MessagePrinterEJB</ejb-name> <ejb-class> com.learnweblogic.examples.ch10.textmessage.MessagePrinterBean </ejb-class> <transaction-type>Container</transaction-type> <message-driven-destination> <jms-destination-type> javax.jms.Queue </jms-destination-type> </message-driven-destination> </message-driven> </enterprise-beans> </ejb-jar> .
Message-driven EJBs also require a weblogic-ejb-jar.xml deployment descriptor. Like other EJBs, this deployment descriptor contains deployment information that is WebLogic-specific or simply not specified by the standard ejb-jar.xml deployment descriptor.
The only required element for a message-driven EJB is the <destination-jndi-name>. When the EJB container deploys the message-driven EJB, it uses this Java Naming and Directory Interface (JNDI) name to look up the JMS destination. Unlike other EJB types, a <jndi-name> for the EJB is not required because there is no direct client interaction.
<?xml version="1.0"?> <!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN" "http://www.bea.com/servers/wls600/dtd/weblogic-ejb-jar.dtd"> <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>MessagePrinterEJB</ejb-name> <message-driven-descriptor> <destination-jndi-name> MessageQueue </destination-jndi-name> </message-driven-descriptor> </weblogic-enterprise-bean> </weblogic-ejb-jar>
This example is in the examples/ch10/textmessage/ directory on the accompanying CD-ROM. The build.cmd script will compile and build the ejb and the client classes. The runclient.cmd script runs the JMS client to publish messages.
The message-driven bean class may now be packaged along with the deployment descriptors in an ejb-jar file.
META-INF/ejb-jar.xml META-INF/weblogic-ejb-jar.xml com/learnweblogic/examples/ch10/textmessage/MessagePrinter- Bean.class
Before the ejb-jar file can be deployed in the WebLogic Server, the deployer must ensure that the associated JMS destination exists. In this case, the server must have a JMS queue deployed with the JNDI name MessageQueue.
Once the JMS destination exists, the ejb-jar is deployed by copying the file into the server's applications directory. The deploy.cmd script demonstrates this process.
A client can now indirectly interact with the message-driven EJB by publishing JMS messages to the messages queue.
A message-driven EJB client uses standard JMS message producer code. The JMS client has no idea what consumers will receive the JMS messages—message-driven EJBs or other types of JMS consumers. For a more detailed explanation of JMS message producers, please see Chapter 7.
package com.learnweblogic.examples.ch10.textmessage; public final class TextMessageSenderClient extends BaseClient { private QueueConnection queueConnection = null; private QueueSender queueSender = null; private QueueSession queueSession = null; private Queue queue = null; private TextMessage msg = null; public TextMessageSenderClient(String [] argv) throws Exception { super(argv); try { Context ctx = getInitialContext(); QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(JMS_CONN_FACTORY); queueConnection = factory.createQueueConnection(); // Create a non-transacted JMS Session queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); queue = (Queue) ctx.lookup(JMS_QUEUE); queueSender = queueSession.createSender(queue); msg = queueSession.createTextMessage(); queueConnection.start(); } catch (Exception e) { System.err.println("Error while attempting to "+ "connect to the server and look up the JMS"+ " QueueConnectionFactory."); System.err.println("Please make sure that you have"+ " deployed the JMS Queue and specified the correct"+ " server URL."); e.printStackTrace(); throw e; } } public void send(String message) throws JMSException { try { msg.setText(message); queueSender.send(msg); } catch (JMSException e) { System.err.println("Exception raised while sending"+ "to queue: "+ JMS_QUEUE); e.printStackTrace(); throw e; } }
3.145.202.27