9 Replies Latest reply on Sep 17, 2003 3:44 AM by Olaf

    MDB listens to one queue and sends to queue two

    ah123 Newbie

      I have the following senario:

      A MDB is listening to a queue, onMessage method I'm able to print the message from client A. However, in the onMessage method I'd like to create a new message and send it to a different queue so that client A will listen to it.

      So here's my first question, it is possible at all to do that with MDB and JMS?
      Second, what should the jboss.xml format be for multiple queues? This is what I have right now:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS//EN" "http://www.jboss.org/j2ee/dtd/jboss.dtd">



      <enterprise-beans>

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

      </enterprise-beans>



      Here's what I'm trying to achieve: Client A is trying to get some inventory calculation from several companies. I want to parallel the process so that I'll send say 6 messages (one for each company) to a MDB. Each message will be processed simultaneously by the mdb and send it's results back to client A. What would be the be configuration for that?

      Thanks a lot,

      -A.

        • 1. Re: MDB listens to one queue and sends to queue two
          Adrian Brock Master

          You should setup <resource-ref>s for the connection
          factories and queues.

          Regards,
          Adrian

          • 2. Re: MDB listens to one queue and sends to queue two
            Olaf Newbie

            Hi JBoss-Users,
            it took me quite a long time to figure this out, so I
            want to share my solution with you.

            The attached file includes a client sending a message
            to a MDB an getting a response on another queue.

            To get the right response, a selector is used. Place
            the jar File in your JBoss-Home. The zip-file contains
            the sources for eclipse and myeclipseide.

            Send questions to olaf[at]uni-mannheim.de

            Kind regards

            • 3. Re: MDB listens to one queue and sends to queue two
              ah123 Newbie

              I'm fairly new to JMS. Could you please be more specific and post or point me to an example. I'm running JBoss 3.2.1.

              Thanks a lot,

              A.

              • 4. Re: MDB listens to one queue and sends to queue two
                ah123 Newbie

                I should have specified, my previous reply was to Adrian.

                • 5. Re: MDB listens to one queue and sends to queue two
                  Adrian Brock Master

                  Here is an example from the testsuite:
                  It constructs the java:comp/env namespace

                  e.g. lookup("java:/comp/env/jms/MyQueueConnection");

                  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/j2ee/dtds/ejb-jar_2_0.dtd">

                  <ejb-jar>
                  Queue Publisher
                  <display-name>PublisherBean</display-name>
                  <enterprise-beans>

                  <ejb-name>JMSSession</ejb-name>
                  org.jboss.test.jmsra.bean.JMSSessionHome
                  org.jboss.test.jmsra.bean.JMSSession
                  <ejb-class>org.jboss.test.jmsra.bean.JMSSessionBean</ejb-class>
                  <session-type>Stateless</session-type>
                  <transaction-type>Container</transaction-type>


                  <display-name>Publisher</display-name>
                  <ejb-name>QueuePublisher</ejb-name>
                  org.jboss.test.jmsra.bean.PublisherHome
                  org.jboss.test.jmsra.bean.Publisher
                  <ejb-class>org.jboss.test.jmsra.bean.PublisherBean</ejb-class>
                  <session-type>Stateless</session-type>
                  <transaction-type>Container</transaction-type>
                  <resource-ref>
                  A Queue ConnectionFactory
                  <res-ref-name>jms/MyQueueConnection</res-ref-name>
                  <res-type>javax.jms.QueueConnectionFactory</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  <resource-ref>
                  A Queue
                  <res-ref-name>jms/QueueName</res-ref-name>
                  <res-type>javax.jms.Queue</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  <ejb-ref>
                  <ejb-ref-name>ejb/PublisherCMP</ejb-ref-name>
                  <ejb-ref-type>Entity</ejb-ref-type>
                  org.jboss.test.jmsra.bean.PublisherCMPHome
                  org.jboss.test.jmsra.bean.PublisherCMP
                  <ejb-link>PublisherCMP</ejb-link>
                  </ejb-ref>


                  <display-name>TopicPublisher</display-name>
                  <ejb-name>TopicPublisher</ejb-name>
                  org.jboss.test.jmsra.bean.PublisherHome
                  org.jboss.test.jmsra.bean.Publisher
                  <ejb-class>org.jboss.test.jmsra.bean.TopicPublisherBean</ejb-class>
                  <session-type>Stateless</session-type>
                  <transaction-type>Container</transaction-type>
                  <resource-ref>
                  A Topic ConnectionFactory
                  <res-ref-name>jms/MyTopicConnection</res-ref-name>
                  <res-type>javax.jms.TopicConnectionFactory</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  <resource-ref>
                  A Topic
                  <res-ref-name>jms/TopicName</res-ref-name>
                  <res-type>javax.jms.Topic</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  <ejb-ref>
                  <ejb-ref-name>ejb/PublisherCMP</ejb-ref-name>
                  <ejb-ref-type>Entity</ejb-ref-type>
                  org.jboss.test.jmsra.bean.PublisherCMPHome
                  org.jboss.test.jmsra.bean.PublisherCMP
                  <ejb-link>PublisherCMP</ejb-link>
                  </ejb-ref>


                  <display-name>QueueRec</display-name>
                  <ejb-name>QueueRec</ejb-name>
                  org.jboss.test.jmsra.bean.QueueRecHome
                  org.jboss.test.jmsra.bean.QueueRec
                  <ejb-class>org.jboss.test.jmsra.bean.QueueRecBean</ejb-class>
                  <session-type>Stateless</session-type>
                  <transaction-type>Container</transaction-type>
                  <resource-ref>
                  A Queue ConnectionFactory
                  <res-ref-name>jms/MyQueueConnection</res-ref-name>
                  <res-type>javax.jms.QueueConnectionFactory</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  <resource-ref>
                  A Queue
                  <res-ref-name>jms/QueueName</res-ref-name>
                  <res-type>javax.jms.Queue</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>


                  <display-name>Publisher Entity</display-name>
                  <ejb-name>PublisherCMP</ejb-name>
                  org.jboss.test.jmsra.bean.PublisherCMPHome
                  org.jboss.test.jmsra.bean.PublisherCMP
                  <ejb-class>org.jboss.test.jmsra.bean.PublisherCMPBean</ejb-class>
                  <persistence-type>Container</persistence-type>
                  <prim-key-class>java.lang.Integer</prim-key-class>
                  True
                  <cmp-version>1.x</cmp-version>
                  <cmp-field>
                  Nr
                  <field-name>nr</field-name>
                  </cmp-field>
                  <primkey-field>nr</primkey-field>

                  <message-driven>
                  <ejb-name>TopicAdapter</ejb-name>
                  <ejb-class>org.jboss.test.jmsra.bean.TopicAdapter</ejb-class>
                  <message-selector></message-selector>
                  <transaction-type>Container</transaction-type>
                  <message-driven-destination>
                  <destination-type>javax.jms.Topic</destination-type>
                  <subscription-durability>NonDurable</subscription-durability>
                  </message-driven-destination>
                  <resource-ref>
                  A Queue ConnectionFactory
                  <res-ref-name>jms/MyQueueConnection</res-ref-name>
                  <res-type>javax.jms.QueueConnectionFactory</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  <resource-ref>
                  A Queue
                  <res-ref-name>jms/QueueName</res-ref-name>
                  <res-type>javax.jms.Queue</res-type>
                  <res-auth>Container</res-auth>
                  </resource-ref>
                  </message-driven>
                  </enterprise-beans>
                  <assembly-descriptor>
                  <container-transaction>

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

                  <trans-attribute>Required</trans-attribute>
                  </container-transaction>
                  </assembly-descriptor>
                  </ejb-jar>

                  jboss.xml
                  <?xml version="1.0" encoding="utf-8"?>


                  false
                  <resource-managers>
                  <resource-manager>
                  <res-name>queuefactoryref</res-name>
                  <res-jndi-name>java:/JmsXA</res-jndi-name>
                  </resource-manager>
                  <resource-manager>
                  <res-name>queueref</res-name>
                  <res-jndi-name>queue/testQueue</res-jndi-name>
                  </resource-manager>
                  <resource-manager>
                  <res-name>topicfactoryref</res-name>
                  <res-jndi-name>java:/JmsXA</res-jndi-name>
                  </resource-manager>
                  <resource-manager>
                  <res-name>topicref</res-name>
                  <res-jndi-name>topic/testTopic</res-jndi-name>
                  </resource-manager>
                  <resource-manager>
                  <res-name>recqueueref</res-name>
                  <res-jndi-name>queue/A</res-jndi-name>
                  </resource-manager>
                  </resource-managers>

                  <enterprise-beans>

                  <ejb-name>QueuePublisher</ejb-name>
                  <jndi-name>TxPublisher</jndi-name>
                  <configuration-name>Standard Stateless SessionBean</configuration-name>
                  <resource-ref>
                  <res-ref-name>jms/MyQueueConnection</res-ref-name>
                  <resource-name>queuefactoryref</resource-name>
                  </resource-ref>
                  <resource-ref>
                  <res-ref-name>jms/QueueName</res-ref-name>
                  <resource-name>queueref</resource-name>
                  </resource-ref>
                  <ejb-ref>
                  <ejb-ref-name>ejb/PublisherCMP</ejb-ref-name>
                  <jndi-name></jndi-name>
                  </ejb-ref>


                  <ejb-name>TopicPublisher</ejb-name>
                  <jndi-name>TxTopicPublisher</jndi-name>
                  <configuration-name>Standard Stateless SessionBean</configuration-name>
                  <resource-ref>
                  <res-ref-name>jms/MyTopicConnection</res-ref-name>
                  <resource-name>topicfactoryref</resource-name>
                  </resource-ref>
                  <resource-ref>
                  <res-ref-name>jms/TopicName</res-ref-name>
                  <resource-name>topicref</resource-name>
                  </resource-ref>
                  <ejb-ref>
                  <ejb-ref-name>ejb/PublisherCMP</ejb-ref-name>
                  <jndi-name></jndi-name>
                  </ejb-ref>


                  <ejb-name>QueueRec</ejb-name>
                  <jndi-name>QueueRec</jndi-name>
                  <configuration-name>Standard Stateless SessionBean</configuration-name>
                  <resource-ref>
                  <res-ref-name>jms/MyQueueConnection</res-ref-name>
                  <resource-name>queuefactoryref</resource-name>
                  </resource-ref>
                  <resource-ref>
                  <res-ref-name>jms/QueueName</res-ref-name>
                  <resource-name>recqueueref</resource-name>
                  </resource-ref>


                  <ejb-name>PublisherCMP</ejb-name>
                  <jndi-name>PublisherCMP</jndi-name>

                  <message-driven>
                  <ejb-name>TopicAdapter</ejb-name>
                  <configuration-name>Standard Message Driven Bean</configuration-name>
                  <destination-jndi-name>topic/testTopic</destination-jndi-name>
                  <resource-ref>
                  <res-ref-name>jms/MyQueueConnection</res-ref-name>
                  <resource-name>queuefactoryref</resource-name>
                  </resource-ref>
                  <resource-ref>
                  <res-ref-name>jms/QueueName</res-ref-name>
                  <resource-name>queueref</resource-name>
                  </resource-ref>
                  </message-driven>
                  </enterprise-beans>



                  Regards,
                  Adrian

                  • 6. Re: MDB listens to one queue and sends to queue two
                    ah123 Newbie

                    Thanks a lot for your suggestions. They both worked even though they have different solutions. However, I'm still not sure about a few things.

                    Olaf,
                    Why xBase-queue-service.xml necessary? Is that part of the J2EE spec, or it is used instead of assigning resource-ref?

                    Adrain,
                    I've also tried your solution, where the client uses testQueue to send a message. My MDB listens to it (via onMessage() method) and uses jms/secondQueue to send a message to a different listening client. The problem is that when send one message from the client, onMessage on the MDB is called many times (about 20 times) and I'm not sure how to stop it. The other problem that I face is with the othe client. I want it to listen to the jms/secondQueue but I'm getting an exception saying:
                    javax.naming.NameNotFoundException: comp not bound
                    here are my files

                    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 >

                    No Description.
                    <display-name>Generated by XDoclet</display-name>

                    <enterprise-beans>

                    <message-driven >
                    <![CDATA[Session Bean Template]]>
                    <display-name>Test MDB</display-name>

                    <ejb-name>test/mdb</ejb-name>

                    <ejb-class>test.mdb.TestMDBBean</ejb-class>

                    <transaction-type>Container</transaction-type>
                    <message-driven-destination>
                    <destination-type>javax.jms.Queue</destination-type>
                    <subscription-durability>Durable</subscription-durability>
                    </message-driven-destination>
                    <security-identity>
                    Use a role that is not assigned to any users to
                    access restricted server side functionallity
                    <run-as>
                    <role-name>Server</role-name>
                    </run-as>
                    </security-identity>


                    <resource-ref>
                    A Queue
                    <res-ref-name>jms/secondQueue</res-ref-name>
                    <res-type>javax.jms.Queue</res-type>
                    <res-auth>Container</res-auth>
                    </resource-ref>


                    </message-driven>


                    </enterprise-beans>

                    <assembly-descriptor >

                    <security-role>
                    The role used to prevent access to the PrivateEntity
                    bean from external users.

                    <role-name>Server</role-name>
                    </security-role>


                    <container-transaction>

                    <ejb-name>test/mdb</ejb-name>
                    <method-name>*</method-name>

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

                    </assembly-descriptor>

                    </ejb-jar>

                    jboss.xml:

                    <?xml version="1.0" encoding="UTF-8"?>
                    <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS//EN" "http://www.jboss.org/j2ee/dtd/jboss.dtd">


                    false
                    <resource-managers>
                    <resource-manager>
                    <res-name>queueref</res-name>
                    <res-jndi-name>queue/testQueue</res-jndi-name>
                    </resource-manager>
                    </resource-managers>

                    <enterprise-beans>

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

                    <resource-ref>
                    <res-ref-name>jms/secondQueue</res-ref-name>
                    <resource-name>queueref</resource-name>
                    </resource-ref>

                    </message-driven>

                    </enterprise-beans>





                    • 7. Re: MDB listens to one queue and sends to queue two
                      Adrian Brock Master

                      You are sending the message back to the same queue
                      that the MDB is listening to. You have written a fork bomb.

                      The java:comp/env namespace is only available to the MDB.
                      You should lookup the global jndi-name i.e. test/testQueue
                      or whatever queue you use for the reply.

                      Regards,
                      Adrian

                      • 8. Re: MDB listens to one queue and sends to queue two
                        ah123 Newbie

                        I've modified that to point to the same queue. The MDB gets the message once and replies to it. But still the client doesn't get a response back from the MDB. It gets a null message back.

                        session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);


                        connection.start();
                        QueueReceiver receiver = session.createReceiver(queue);

                        TextMessage tm = (TextMessage) receiver.receive(5000);

                        • 9. Re: MDB listens to one queue and sends to queue two
                          Olaf Newbie

                          Hi,
                          the -service.xml is for establishing the return
                          queue on the start up of jboss. The queues
                          for MDBs are created automatically, but as
                          I am using a return queue it doesn't work.

                          Take a look at the excellent workbook at
                          oreilly and if you have time, buy the commercial
                          docs. 10 Euros is nothing compared to bea
                          or websphere.

                          Olaf