3 Replies Latest reply on Nov 19, 2015 4:12 PM by gberish

    Why can't MDB lookup 2nd Queue to return message to standalone Java client?

    gberish

      The MDB code below deploys. And it successfully listens for messages sent by my standalone Java Client.

       

      Extract of the WildFly server.log is below.

      -- WildFly was started with nothing deployed.

      -- Then jmsTest.ear was deployed with my MDB. 

      -- Then I used the Java Client to send a test message.

       

      See server.log below:

      The MDB deploys.

      onMessage()receives the message from the Java Client.

      Looks up DefaultJMSConnectionFactory ok

      Establishes a Connection ok, and

      Instantiates a Session ok.

      But it throws an exception when it tries to look up the 2nd Queue to which the Java Client listens.


      What am I doing wrong?

      [note: Yes, I'd love to be able to inject the ConnectionFactory, Connection, Session and 2nd Queue.  I tried and failed.  Hence JNDI lookups.  If anyone can tell me how to inject them that would be great.]

       

      HERE'S THE CODE I ADDED TO standalone-full.xml

      <jms-queue name="goSvrReceiveQueue">

        <entry name="java:/jboss/exported/jms/goSvrReceiveQueue"/>

        <durable>true</durable>

      </jms-queue>

      <jms-queue name="goSvrSendQueue">

        <entry name="java:/jboss/exported/jms/goSvrSendQueue"/>

        <durable>true</durable>

      </jms-queue>

       

      The MDB injects goSvrReceiveQueue ok, because it hears the messages from the Java Client. It just fails when it tries to look up goSvrSendQueue.

       

      HERE IS THE MDB CODE:

      package org.america3.gotest.server.messaging;

      ALL IMPORTS

      @MessageDriven(

        activationConfig ={

          @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),

          @ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),

          @ActivationConfigProperty(propertyName="destination", propertyValue="java:/jms/goSvrReceiveQueue")},

        mappedName = "JmsTestMsgBean")

         

      public class JmsTestMsgBean implements MessageListener {

       

        private ConnectionFactory factory      = null;

        private Connection        connection   = null;

        private Session           session      = null;

        private Queue             svrSendQueue = null;

       

        // constructor

        public JmsTestMsgBean () {

          try {

            System.out.print("\nMDB:constructor():  beg");

           

            Context ctx = new InitialContext();   

            System.out.print("\n  MDB:constructor():  obtained InitialContext");

            System.out.print("\n  MDB:constructor():  "+ ctx);

       

            factory = (ConnectionFactory) ctx.lookup("java:/jboss/DefaultJMSConnectionFactory");

            System.out.print("\n  MDB:constructor():  Connection Factory looked up");

            System.out.print("\n  MDB:constructor():  " + factory);

           

            Connection connection = factory.createConnection("jmsuser", "jmsuser@123");  

            System.out.print("\n  MDB:constructor():  Connection established");

            System.out.print("\n  MDB:constructor():  " + connection);

           

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

            System.out.print("\n  MDB:constructor():  Session instantiated");

            System.out.print("\n  MDB:constructor():  " + session);

           

            svrSendQueue = (Queue) ctx.lookup("java:/jms/goSvrSendQueue");

            System.out.print("\n  MDB:constructor():  svrSendQueus looked up");

            System.out.print("\n  MDB:constructor():  " + svrSendQueue);

       

            System.out.print("\nMDB:constructor():  end");

          }catch(Exception e) {

            System.out.print("\n  MDB:constructor():  Exception - " + e.getClass().getName());

            System.out.print("\n  MDB:constructor():  msg - " + e.getMessage());

            System.out.print("\n  MDB:constructor():  close any connection");

            if(connection != null)

              try {

                connection.close();

              } catch (JMSException e1) {

                e1.printStackTrace();

              }

            System.out.print("\nMDB:constructor(): end - w/Exception");

          }

        }

         

        @PostConstruct

        public void myInit () {

          System.out.print("\nMDB:myInit()     : Construction completed. called try:#8");

        }

        @PreDestroy

        public void myDestroy () throws JMSException {

          System.out.print("/nMDB:myDestroy()  : called to close any connection");

          if(connection != null) connection.close();

        }

       

        public void onMessage(Message msg) {

          System.out.print("\nMDB:onMessage(): begin");

          try {

            String textReceived = (String)(((ObjectMessage)msg).getObject());

            System.out.print("\n  MDB:onMessage()  :  msg Received - \"" + textReceived + "\"");

            System.out.print("\nMDB:onMessage(): end - successfully");

          } catch (JMSException e1) {

            System.out.print("\n  MDB:onMessage()  : Exception - " + e1.getClass().getName());

            System.out.print("\n  MDB:onMessage()  : msg       - " + e1.getMessage());

            System.out.print("\n  MDB:onMessage()  : close any connection");

            if(connection != null)

              try {

                connection.close();

              } catch (JMSException e) {

                e.printStackTrace();

              }

            System.out.print("\nMDB:onMessage(): end - w/Exception");

          }

          /************************************************

          * To Do Next ... after I can get the send queue *

          * Create Message Producer                       *

          * Send reply message                            * 

          *************************************************/

        }

      }

       

      HERE IS AN EXTRACT OF WILDFLY'S server.log

      INFO  ... JBoss Modules version 1.4.3.Final

      INFO  ... JBoss MSC version 1.2.6.Final

      INFO  ... WFLYSRV0049: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) starting

      ...

      INFO  ... HQ221007: Server is now live

      INFO  ... HQ221001: HornetQ Server version 2.4.7.Final (2.4.7.Final, 124) [110ad015-7f84-11e5-99db-a1c8fb17f77e]

      INFO  ... HQ221003: trying to deploy queue jms.queue.DLQ

      INFO  ... WFLYMSG0002: Bound messaging object to jndi name java:jboss/exported/jms/RemoteConnectionFactory

      INFO  ... WFLYMSG0002: Bound messaging object to jndi name java:/ConnectionFactory

      INFO  ... HQ221003: trying to deploy queue jms.queue.TestQ

      INFO  ... HQ221003: trying to deploy queue jms.queue.goSvrSendQueue

      INFO  ... HQ221003: trying to deploy queue jms.queue.goSvrReceiveQueue

      INFO  ... HQ221003: trying to deploy queue jms.queue.ExpiryQueue

      INFO  ... WFLYJCA0007: Registered connection factory java:/JmsXA

      INFO  ... HornetQ resource adaptor started

      INFO  ... IJ020002: Deployed: file://RaActivatorhornetq-ra

      INFO  ... WFLYMSG0002: Bound messaging object to jndi name java:jboss/DefaultJMSConnectionFactory

      INFO  ... WFLYJCA0002: Bound JCA ConnectionFactory [java:/JmsXA]

      INFO  ... WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management

      INFO  ... WFLYSRV0051: Admin console listening on http://127.0.0.1:9990

      ...

      INFO  ... WFLYSRV0025: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) started in 3893ms - Started 246 of 420 services (228 services are lazy, passive or on-demand)

      TIME: 03:47,253

      ...

      TIME: 03:56,279 Deployed jmsTest.ear to <JBOSS_HOME>*\bpWildFly\standalone\deployments

      INFO  ... WFLYDR0001: Content added ...

      INFO  ... WFLYSRV0027: Starting deployment of "jmsTest.ear" (runtime-name: "jmsTest.ear")

      INFO  ... WFLYSRV0207: Starting subdeployment (runtime-name: "jmsTest.jar")

      INFO  ... WFLYEJB0042: Started message driven bean 'JmsTestMsgBean' with 'hornetq-ra.rar' resource adapter

      INFO  ... WFLYSRV0010: Deployed "jmsTest.ear" (runtime-name : "jmsTest.ear")

      #: The following were all preceded by "(default-threads - 1)"

      INFO  ...

      INFO  ... MDB:constructor():  beg

      INFO  ... MDB:constructor():  obtained InitialContext

      INFO  ... MDB:constructor(): javax.naming.InitialContext@283b9138

      INFO  ... MDB:constructor():  Connection Factory looked up

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRAConnectionFactoryImpl@89b0482

      INFO  ... MDB:constructor():  Connection established

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRASessionFactoryImpl@6aabb8ef

      INFO  ... MDB:constructor():  Session instantiated

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRASession@345644d

      INFO  ... MDB:constructor():  Exception - javax.naming.NameNotFoundException

      INFO  ... MDB:constructor():  msg       - jms/goSvrSendQueue -- service jboss.naming.context.java.jms.goSvrSendQueue

      INFO  ... MDB:constructor():  close any connection

      INFO  ... MDB:constructor(): end - w/Exception

       

      INFO  ... MDB:constructor():  beg

      INFO  ... MDB:constructor():  obtained InitialContext

      INFO  ... MDB:constructor(): javax.naming.InitialContext@2baa7b3a

      INFO  ... MDB:constructor():  Connection Factory looked up

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRAConnectionFactoryImpl@89b0482

      INFO  ... MDB:constructor():  Connection established

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRASessionFactoryImpl@7af2d0e

      INFO  ... MDB:constructor():  Session instantiated

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRASession@16e52215

      INFO  ... MDB:constructor():  Exception - javax.naming.NameNotFoundException

      INFO  ... MDB:constructor():  msg       - jms/goSvrSendQueue -- service jboss.naming.context.java.jms.goSvrSendQueue

      INFO  ... MDB:constructor():  close any connection

      #: The following were preceded by "(Thread-1 (HornetQ-client-global-threads-1681291865))"

      INFO  ... MDB:constructor(): end - w/Exception

      INFO  ... MDB:constructor():  beg

      INFO  ... MDB:constructor():  obtained InitialContext

      INFO  ... MDB:constructor(): javax.naming.InitialContext@24e86645

      INFO  ... MDB:constructor():  Connection Factory looked up

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRAConnectionFactoryImpl@89b0482

      INFO  ... MDB:constructor():  Connection established

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRASessionFactoryImpl@221d7da5

      INFO  ... MDB:constructor():  Session instantiated

      INFO  ... MDB:constructor(): org.hornetq.ra.HornetQRASession@14254457

      INFO  ... MDB:constructor():  Exception - javax.naming.NameNotFoundException

      INFO  ... MDB:constructor():  msg       - jms/goSvrSendQueue -- service jboss.naming.context.java.jms.goSvrSendQueue

      INFO  ... MDB:constructor():  close any connection

      INFO  ... MDB:constructor(): end - w/Exception

      TIME: 03:56,835

      ...

      ...

      TIME: 04:31,840 Java Client sends message

      INFO  ... MDB:myInit()     : Construction completed. called try:#8

      INFO  ... MDB:onMessage(): begin

      INFO  ... MDB:onMessage()  :  msg Received - "Return Me to Sender"

      #:  That is correct text sent by Java Client

      #:  For some reason the "end" line from onMessage() did not print.

       

      #:  Later WF did some clean up

      TIME: 13:44,353

      INFO  ... WFLYDR0009: Content ****\standalone\data\content\70\214eac7db6bd80cdd3d27b7b623bbb64ca8644 is obsolete and will be removed

      INFO  ... WFLYDR0002: Content removed from location ****\standalone\data\content\70\214eac7db6bd80cdd3d27b7b623bbb64ca8644\content

        • 1. Re: Why can't MDB lookup 2nd Queue to return message to standalone Java client?
          jaysensharma

          Your JMS Queue's JNDI name is :    "java:/jboss/exported/jms/goSvrSendQueue"

           

          But your MDB Code is trying to look it up using a different JNDI name , Why ?  svrSendQueue = (Queue) ctx.lookup("java:/jms/goSvrSendQueue");

           


          Does the following work:


          @MessageDriven(
            activationConfig ={
              @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
              @ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),
              @ActivationConfigProperty(propertyName="destination", propertyValue="jms/goSvrReceiveQueue")},
              mappedName = "JmsTestMsgBean")
          
          .
          .
          .
                svrSendQueue = (Queue) ctx.lookup("java:/jboss/exported/jms/goSvrSendQueue");      // NOTICE
                System.out.print("\n  MDB:constructor():  svrSendQueus looked up");
                System.out.print("\n  MDB:constructor():  " + svrSendQueue);
          
          
          
          
          
          

           

           

           

           

          Output on WildFly 8.2.1

           

          14:35:47,659 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.2.1.Final "Tweek" started in 2588ms - Started 277 of 332 services (103 services are lazy, passive or on-demand)
          14:35:47,709 INFO  [stdout] (default-threads - 1)   MDB:constructor():  org.hornetq.ra.HornetQRAConnectionFactoryImpl@60f639fe
          14:35:47,709 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection established
          14:35:47,710 INFO  [stdout] (default-threads - 1)   MDB:constructor():  org.hornetq.ra.HornetQRASessionFactoryImpl@68bc1c39
          14:35:47,710 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Session instantiated
          14:35:47,710 INFO  [stdout] (default-threads - 1)   MDB:constructor():  org.hornetq.ra.HornetQRASession@24cc9d46
          14:35:47,710 INFO  [stdout] (default-threads - 1)   MDB:constructor():  svrSendQueus looked up
          14:35:47,710 INFO  [stdout] (default-threads - 1)   MDB:constructor():  HornetQQueue[goSvrSendQueue]
          14:35:47,716 INFO  [stdout] (default-threads - 1) MDB:constructor():  end
          14:35:47,716 INFO  [stdout] (default-threads - 1) MDB:constructor():  beg
          14:35:47,716 INFO  [stdout] (default-threads - 1)   MDB:constructor():  obtained InitialContext
          14:35:47,716 INFO  [stdout] (default-threads - 1)   MDB:constructor():  javax.naming.InitialContext@478209e6
          14:35:47,716 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection Factory looked up
          14:35:47,718 INFO  [stdout] (default-threads - 1)   MDB:constructor():  org.hornetq.ra.HornetQRAConnectionFactoryImpl@60f639fe
          14:35:47,719 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection established
          14:35:47,719 INFO  [stdout] (default-threads - 1)   MDB:constructor():  org.hornetq.ra.HornetQRASessionFactoryImpl@7cd26b5b
          14:35:47,719 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Session instantiated
          14:35:47,719 INFO  [stdout] (default-threads - 1)   MDB:constructor():  org.hornetq.ra.HornetQRASession@ab6940a
          14:35:47,719 INFO  [stdout] (default-threads - 1)   MDB:constructor():  svrSendQueus looked up
          14:35:47,720 INFO  [stdout] (default-threads - 1)   MDB:constructor():  HornetQQueue[goSvrSendQueue]
          
          
          
          
          

           

           

          Additionally :   the java:jboss/exported/ context, entries bound to this context are accessible over remote JNDI.  If you want to do ONLY a local lookup for your Queues then it is better to bind it to a JNDI name without "java:jboss/exported/"   like  "java:/jms/goSvrSendQueue"

          • 2. Re: Why can't MDB lookup 2nd Queue to return message to standalone Java client?
            jaysensharma

            OR:

             

            If no jndi prefix is defined by default during lookuup then the  "java:" should be the default Name space where the JNDI object name will be found so you can also try the following :

             

                  factory = (ConnectionFactory) ctx.lookup("jboss/DefaultJMSConnectionFactory");    // Should work
                  // Even if the actual JNDI name is: java:jboss/DefaultJMSConnectionFactor
            .
            .
                  svrSendQueue = (Queue) ctx.lookup("jboss/exported/jms/goSvrSendQueue");          // Should work
                  // Even if the actual JNDI name is: java:/jboss/exported/jms/goSvrSendQueue.  So while doing manual jndo lookup using InitialContext look approach then either use the complete JNDI name  or use as above.
            
            
            
            • 3. Re: Why can't MDB lookup 2nd Queue to return message to standalone Java client?
              gberish

              Hi Jay:

              That works perfectly.  And once I had the Queue, the rest of the code worked as it should.  I.e.  Instantiating a MessageProducer to that Queue, and sending a message to it.

               

              For other beginners please note:

               

              This worked even with "java:/ " left in:

              ConnectionFactory factory = (ConnectionFactory) ctx.lookup("java:/jboss/DefaultJMSConnectionFactory");

                 

              But  to look up the Queue I defined in standalone-full.xml I had to take out the "java:/"

              Queue svrSendQueue = (Queue) ctx.lookup("jboss/exported/jms/goSvrSendQueue");

               

              And did need to make both the MDB's listening Queue (svrReceiveQueue) and it's send to Queue (svrSendQueue) exportable, because the external standalone Java Client will need access to both if it is going to exchange messages with server.

               

              I have no idea why "java:/" works in one and not in the other.  While its not part of the original question, if anyone else sees why please add it. WildFly might be great.  But it is not easy to understand why it does things like this differently.