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

    Help needed : Message driven bean does not run 'Hello World

    fredatwork

      Hello,

      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 :

      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 information, here are the ejb-jar.xml and jboss.xml descriptors that are deployed on JBoss :

      <?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 >

      <![CDATA[No Description.]]>
      <display-name>Generated by XDoclet</display-name>

      <enterprise-beans>

      <!-- Session Beans -->

      <![CDATA[]]>

      <ejb-name>CalculationManager</ejb-name>

      com.rubis.app.calculations.interfaces.CalculationManagerHome
      com.rubis.app.calculations.interfaces.CalculationManager
      <local-home>com.rubis.app.calculations.interfaces.CalculationManagerLocalHome</local-home>
      com.rubis.app.calculations.interfaces.CalculationManagerLocal
      <ejb-class>com.rubis.app.calculations.ejb.CalculationManagerSession</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>



      <!--
      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 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 markup for those beans.
      -->

      <!-- Message Driven Beans -->
      <message-driven >
      <![CDATA[]]>

      <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 >

      <ejb-name>CalculationManager</ejb-name>
      <method-name>*</method-name>

      <trans-attribute>Required</trans-attribute>
      </container-transaction>

      <!-- finder transactions -->
      </assembly-descriptor>

      </ejb-jar>

      <?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">



      <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 , and <message-driven></message-driven>
      markup for those beans.
      -->


      <ejb-name>CalculationManager</ejb-name>
      <jndi-name>CalculationManagerBean</jndi-name>
      <local-jndi-name>CalculationManagerLocal</local-jndi-name>

      <method-attributes>
      </method-attributes>


      <message-driven>
      <ejb-name>CalculationExecution</ejb-name>
      <destination-jndi-name>queue/testQueue</destination-jndi-name>
      </message-driven>

      </enterprise-beans>

      <resource-managers>
      </resource-managers>