1 Reply Latest reply on Aug 1, 2004 11:28 AM by fredatwork

    Message driven bean does not run

    fredatwork Newbie

      Hello,

      Please ignored previous message (I reformatted it here with appropriatate coding tags for better reading).

      I'm new to JMS and Message driven beans (but I'm not new to JBoss and session/entity beans).

      I run JBoss 3.2.2 on Windows XP ('default' mode). I've build a prototype to play with my first message-driven bean :
      - I have a message-driven bean called 'CalculationExecutionBean'. Its onMessage() method printsthe good-old-message "Hello World !" to the server's standard output
      - I have a client that sends a basic 'Hello World !' test message.

      The client runs well (JNDi context is created, queue factory and queue are found, JMS connection and session are created) and appearently a message is sent correctly. But the CalculationExecution bean does not say anything in its onMessage() method ... It looks like its onMessage() method is not triggered.

      I've tried different queues that come preconfigured with JBoss : 'queue/A' and 'queue/testQueue'. If I change the queue name on the client with a non appropriate name, the client fails with a NamingException (ok). If I change the name in the jboss.xml descriptor (through XDoclet generation), JBoss warns me because it cannot find the queue with the non-appropriate name (ok). Therefore, I think the JNDi names that I'm using are all right ('queue/A' or 'queue/testQueue'), but still I do not understand why the message-driven bean does not run.

      Can anyone help me with this ?

      Here is the CalculationExecutionBean source code:

      import javax.ejb.EJBException;
      import javax.ejb.MessageDrivenBean;
      import javax.ejb.MessageDrivenContext;
      import javax.jms.Message;
      import javax.jms.MessageListener;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      import org.apache.log4j.Logger;
      
      /**
       * @ejb.bean
       * name="CalculationExecution"
       * jndi-name="CalculationExecutionBean"
       * transaction-type="Container"
       * acknowledge-mode="Auto-acknowledge"
       * destination-type="javax.jms.Queue"
       * subscription-durability="Durable"
       *
       *@jboss.destination-jndi-name
       * name="queue/testQueue"
       */
      
      
      public class CalculationExecutionBean implements MessageDrivenBean, MessageListener {
      
       /** Message Driven Context **/
       private MessageDrivenContext ejbContext;
      
       /** Jndi context **/
       private Context jndiContext;
      
       /** Logger **/
       static private Logger logger = Logger.getLogger(CalculationExecutionBean.class);
      
       /**
       * Bean creation method
       */
       public void ejbCreate() {
       // Do nothing
       }
      
       /**
       * Remove method
       */
       public void ejbRemove() {
       // Do nothing
       }
      
       /**
       * @see javax.ejb.MessageDrivenBean#setMessageDrivenContext(javax.ejb.MessageDrivenContext)
       */
       public void setMessageDrivenContext(MessageDrivenContext mdc) throws EJBException {
       try {
       this.ejbContext = mdc;
       this.jndiContext = new InitialContext();
       } catch (NamingException e) {
       logger.error("Cannot create initial context for message-drive bean " + this.getClass().getName());
       throw new EJBException(e);
       }
       }
      
       /**
       * Message receiving method
       * @param message - received message
       */
       public void onMessage(Message message) {
       logger.info("Received message : " + message);
       }
      
      }


      Here is the client that sends the message :
      import java.util.Hashtable;
      
      import javax.jms.JMSException;
      import javax.jms.Queue;
      import javax.jms.QueueConnection;
      import javax.jms.QueueConnectionFactory;
      import javax.jms.QueueSender;
      import javax.jms.QueueSession;
      import javax.jms.TextMessage;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      import org.apache.log4j.Logger;
      import org.apache.log4j.PropertyConfigurator;
      
      public class TestMessage {
      
       /** Logger **/
       static private Logger logger = Logger.getLogger(TestMessage.class);
      
       /**
       * Main method
       * @param args - command line arguments
       */
       public static void main(String args[]) {
       PropertyConfigurator.configure("G:\\rubis_client\\src\\com\\rubis\\client\\log4j\\log4j.properties");
       TestMessage test = new TestMessage();
       }
      
       /**
       * Constructor
       */
       public TestMessage() {
       // Create JNDI context
       InitialContext jndiContext = null;
       try {
       jndiContext = getInitialContext();
       logger.info("Created JNDi context");
       } catch (NamingException e) {
       logger.error("Caught exception " + e.getClass().getName() + " : " + e.getMessage());
       logger.error("Cannot create JNDI context");
       return;
       }
       // Create queue connection factory
       QueueConnectionFactory factory = null;
       try {
       factory = (QueueConnectionFactory) jndiContext.lookup("ConnectionFactory");
       logger.info("Created queue connection factory");
       } catch (NamingException e) {
       logger.error("Caught exception " + e.getClass().getName() + " : " + e.getMessage());
       logger.error("Cannot create queue connection factory");
       return;
       }
       // Create queue
       Queue queue = null;
       try {
       // Creation queue
       String queueName = "queue/testQueue";
       queue = (Queue) jndiContext.lookup(queueName);
       logger.info("Created queue '" + queueName + "'");
       } catch (NamingException e) {
       logger.error("Caught exception " + e.getClass().getName() + " : " + e.getMessage());
       logger.error("Cannot create queue");
       return;
       }
       try {
       // Create JMS connection
       QueueConnection connect = factory.createQueueConnection();
       logger.info("Created JMS connection");
       // Create JMS session
       QueueSession session = connect.createQueueSession(true, 0);
       logger.info("Created JMS session");
       // Create JMS sender
       QueueSender sender = session.createSender(queue);
       logger.info("Create JMS sender");
       // Prepare text message
       TextMessage message = session.createTextMessage();
       message.setText("Hello World !");
       logger.info("Created text message : " + message);
       // Send message
       sender.send(message);
       logger.info("Send message : " + message);
       // Close JMS connection
       connect.close();
       logger.info("Closed JMS connection");
       } catch (JMSException e) {
       logger.error("Caught exception " + e.getClass().getName() + " : " + e.getMessage());
       logger.error("Cannot create jms connection");
       return;
       }
       }
      
       /**
       * Get jndi context
       * @return
       * @throws NamingException
       */
       public static InitialContext getInitialContext() throws NamingException {
       Hashtable props = new Hashtable();
       props.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
       props.put(InitialContext.PROVIDER_URL, "jnp://127.0.0.1:1099");
       return new InitialContext(props);
       }
      
      }


      For your information, here are the ejb-jar.xml and jboss.xml descriptors that are deployed on JBoss :
      ejb-jar.xml :
      <?xml version="1.0" encoding="UTF-8"?>
      <!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 >
      
       <description><![CDATA[No Description.]]></description>
       <display-name>Generated by XDoclet</display-name>
      
       <enterprise-beans>
      
       <!-- Session Beans -->
       <session >
       <description><![CDATA[]]></description>
      
       <ejb-name>CalculationManager</ejb-name>
      
       <home>com.rubis.app.calculations.interfaces.CalculationManagerHome</home>
       <remote>com.rubis.app.calculations.interfaces.CalculationManager</remote>
       <local-home>com.rubis.app.calculations.interfaces.CalculationManagerLocalHome</local-home>
       <local>com.rubis.app.calculations.interfaces.CalculationManagerLocal</local>
       <ejb-class>com.rubis.app.calculations.ejb.CalculationManagerSession</ejb-class>
       <session-type>Stateless</session-type>
       <transaction-type>Container</transaction-type>
      
       </session>
      
       <!--
       To add session beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called session-beans.xml that contains
       the <session></session> markup for those beans.
       -->
      
       <!-- Entity Beans -->
       <!--
       To add entity beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called entity-beans.xml that contains
       the <entity></entity> markup for those beans.
       -->
      
       <!-- Message Driven Beans -->
       <message-driven >
       <description><![CDATA[]]></description>
      
       <ejb-name>CalculationExecution</ejb-name>
      
       <ejb-class>com.rubis.app.calculations.ejb.CalculationExecutionBean</ejb-class>
      
       <transaction-type>Container</transaction-type>
       <acknowledge-mode>Auto-acknowledge</acknowledge-mode>
       <message-driven-destination>
       <destination-type>javax.jms.Queue</destination-type>
       <subscription-durability>Durable</subscription-durability>
       </message-driven-destination>
      
       </message-driven>
      
       <!--
       To add message driven beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called message-driven-beans.xml that contains
       the <message-driven></message-driven> markup for those beans.
       -->
      
       </enterprise-beans>
      
       <!-- Relationships -->
      
       <!-- Assembly Descriptor -->
       <assembly-descriptor >
       <!--
       To add additional assembly descriptor info here, add a file to your
       XDoclet merge directory called assembly-descriptor.xml that contains
       the <assembly-descriptor></assembly-descriptor> markup.
       -->
      
       <!-- finder permissions -->
      
       <!-- finder permissions -->
      
       <!-- transactions -->
       <container-transaction >
       <method >
       <ejb-name>CalculationManager</ejb-name>
       <method-name>*</method-name>
       </method>
       <trans-attribute>Required</trans-attribute>
       </container-transaction>
      
       <!-- finder transactions -->
       </assembly-descriptor>
      
      </ejb-jar>
      


      jboss.xml :
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.2//EN" "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">
      
      <jboss>
      
       <enterprise-beans>
      
       <!--
       To add beans that you have deployment descriptor info for, add
       a file to your XDoclet merge directory called jboss-beans.xml that contains
       the <session></session>, <entity></entity> and <message-driven></message-driven>
       markup for those beans.
       -->
      
       <session>
       <ejb-name>CalculationManager</ejb-name>
       <jndi-name>CalculationManagerBean</jndi-name>
       <local-jndi-name>CalculationManagerLocal</local-jndi-name>
      
       <method-attributes>
       </method-attributes>
       </session>
      
       <message-driven>
       <ejb-name>CalculationExecution</ejb-name>
       <destination-jndi-name>queue/testQueue</destination-jndi-name>
       </message-driven>
      
       </enterprise-beans>
      
       <resource-managers>
       </resource-managers>
      
      </jboss>