12 Replies Latest reply on Dec 5, 2015 10:06 PM by Justin Bertram

    Why does JNDI lookup work in my MDB, but @Resource fail?

    George Berish Novice

      This link offers an elegant alternative to using the full JMS API to deploy a Message Driven Bean able to receive messages and reply.

      https://blogs.oracle.com/arungupta/entry/simple_jms_2_0_sample

       

      But like so many things JBoss, it doesn't work as shown. Can anyone tell me why?

       

      Here's what I pasted below:

      1.  The MDB code,

      2.  The xml I added to standalone-full.xml to create three identical Queues

            a. svrReceiveQueue (listened to by the MDB)

            b. svrSendQueue (used by the MDB to send a reply)

            c. svrTestQueue (a dummy queue to see if I could inject it)

      3.  An extract from the WildFly server log with the output from my MDB's println() statements.

       

      The MDB works fine.  A separate standalone java client sends it a message.  The MDB receives it.  It sends a reply.  And the separate java client receives it. 

       

      So obviously the @MessageDriven annotations work and the MDB listens to svrReceiveQueue. 

      And the JNDI lookups work because it sends a reply to svrSendQueue.

       

      But none of the @Resource annotations I used to inject svrTestQueue worked. 

      Those I commented out fail with a notification of "missing/unsatisfied dependencies" (but no Exception that hints why.) 

      The one @Resource line that I did not comment out just returns null (see sever log).

       

      Note:  In the MDB annotations I had to leave IN "java:" in the JNDI name to make it work.

      In the MDB constructor() I had to leave OUT "java:" from the JNDI name to make it work.

      Don't know why.  Just trial and error.

       

      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 {

        /*

         * these tries all failed with "missing/unsatisfied dependencies.

         *

         * @Resource(mappedName = "jboss/exported/jms/goSvrTestQueue")

         * private Queue svrTestQueue;

         *

         * @Resource(name = "jboss/exported/jms/goSvrTestQueue")

         * private Queue svrTestQueue;

         *

         * @Resource(mappedName = "jms/goSvrTestQueue")

         * private Queue svrTestQueue;

         *

         * @Resource(mappedName = "jms/goSvrTestQueue")

         * private Queue svrTestQueue;

         */

       

          /*

         * And this try just returned null see output below

         */

        @Resource(name = "jms/goSvrTestQueue")

        private Queue svrTestQueue;

       

        private Connection      connection         = null;

        private Session         session            = null;

        private Queue           svrSendQueue       = null;

        private Destination     sendToDestination  = null;

        private MessageProducer msgProducer        = null;

        private final String    jmsSelectorKey     = "MyMessages";

       

        // 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                   :     "+ ctx);

           

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

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

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

           

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

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

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

           

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

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

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

       

            System.out.print("\n  MDB:constructor():  svrTestQueue injected");

            System.out.print("\n                   :     " + this.svrTestQueue);

          

            this.sendToDestination = (Destination) this.svrSendQueue;

            System.out.print("\n  MDB:constructor():  svrSendQueue cast to Destination");

           

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

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

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

         

            this.msgProducer = session.createProducer(sendToDestination);

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

            System.out.print("\n                   :     " + this.msgProducer);

           

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

          }catch(Exception e) {

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

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

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

            if(this.connection != null)

              try {

                this.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. ver #10");

        }

        @PreDestroy

        public void myDestroy () throws JMSException {

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

          }

       

        public void onMessage(Message msg) {

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

          try {

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

            System.out.print("\n  MDB:onMessage()  : received message = \"" + textReceived + "\"");

           

            String msgSelectorValue = msg.getStringProperty(this.jmsSelectorKey);

            System.out.print("\n  MDB:onMessage()  : selector:");

            System.out.print("\n                   :    \"" + msgSelectorValue +"\"");

       

            ObjectMessage replyMsg = session.createObjectMessage();

            System.out.print("\n  MDB:onMessage()  : reply message created");

       

            replyMsg.setObject(new String("Hi. Received your message ok."));

            System.out.print("\n  MDB:onMessage()  : added String as reply Object:");

            System.out.print("\n                   :     \"Hi. Received your message ok.\"");

           

            replyMsg.setStringProperty(this.jmsSelectorKey, msgSelectorValue);     

            System.out.print("\n  MDB:onMessage()  : setting selector property");

            System.out.print("\n                   :  Key");

            System.out.print("\n                   :     \"" + this.jmsSelectorKey + "\"");

            System.out.print("\n                   :  Value");

            System.out.print("\n                   :     \"" + msgSelectorValue + "\"");

        

            msgProducer.send(replyMsg);

            System.out.print("\n  MDB:onMessage()  : message sent");

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

       

          } catch (JMSException e) {

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

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

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

            if(this.connection != null) {

              try {

                this.connection.close();

              } catch (JMSException e1) {

                e1.printStackTrace();

              }

            }

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

          }

        }

      }

       

      2. ADDITIONS TO standalone.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>

       

        <jms-queue name="goSvrTestQueue">

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

          <durable>true</durable>

        </jms-queue>

       

      1. 3. EXTRACT FROM server.log

      ### Started Server.  MDB NOT deployed

      Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0

      14:33:32,895 INFO  JBoss Modules version 1.4.3.Final

      14:33:33,112 INFO  JBoss MSC version 1.2.6.Final

      14:33:33,186 INFO  WFLYSRV0049: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) starting

      ...

      ...

      14:33:36,324 INFO  WFLYSRV0025: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) started in 3827ms - Starte

      d 248 of 422 services (230 services are lazy, passive or on-demand)

      ### Server started

       

      ### Dropped MDB ear pagkage into WildFly/standalone/deployments

      14:35:10,219 INFO  WFLYDR0001: Content added at location ...\standalone

      14:35:10,246 INFO  WFLYSRV0027: Starting deployment of "jmsTest.ear" (runtime-name: "jmsTest.ear")

      14:35:10,316 INFO  WFLYSRV0207: Starting subdeployment (runtime-name: "jmsTest.jar")

      14:35:10,611 INFO  WFLYEJB0042: Started message driven bean 'JmsTestMsgBean' with 'hornetq-ra.rar' resource adapter

      14:35:10,717 INFO  WFLYSRV0010: Deployed "jmsTest.ear" (runtime-name : "jmsTest.ear")

      ### Server instantiates two MDBs

      14:35:10,679 INFO

      14:35:10,682 INFO   MDB:constructor():  beg

      14:35:10,683 INFO     MDB:constructor():  obtained InitialContext

      14:35:10,684 INFO                      :     javax.naming.InitialContext@322fdbef

      14:35:10,684 INFO     MDB:constructor():  Connection Factory looked up

      14:35:10,753 INFO                      : org.hornetq.ra.HornetQRAConnectionFactoryImpl@3cb794fc

      14:35:10,753 INFO     MDB:constructor():  Connection established

      14:35:10,754 INFO                      : org.hornetq.ra.HornetQRASessionFactoryImpl@5bbb3863

      14:35:10,755 INFO     MDB:constructor():  svrSendQueue looked up

      14:35:10,755 INFO                      :     HornetQQueue[goSvrSendQueue]

      14:35:10,755 INFO     MDB:constructor():  svrTestQueue injected

      14:35:10,755 INFO                      :     null

      14:35:10,756 INFO     MDB:constructor():  svrSendQueue cast to Destination

      14:35:10,756 INFO     MDB:constructor():  Session instantiated

      14:35:10,767 INFO                      :     org.hornetq.ra.HornetQRASession@6868ed03

      14:35:10,767 INFO     MDB:constructor():  Producer instantiated

      14:35:10,768 INFO                      : org.hornetq.ra.HornetQRAMessageProducer@56d67485

      14:35:10,779 INFO   MDB:constructor():  end

       

      14:35:10,780 INFO   MDB:constructor():  beg

      14:35:10,780 INFO     MDB:constructor():  obtained InitialContext

      14:35:10,781 INFO                      :     javax.naming.InitialContext@1d15746d

      14:35:10,781 INFO     MDB:constructor():  Connection Factory looked up

      14:35:10,785 INFO                      : org.hornetq.ra.HornetQRAConnectionFactoryImpl@3cb794fc

      14:35:10,786 INFO     MDB:constructor():  Connection established

      14:35:10,786 INFO                      : org.hornetq.ra.HornetQRASessionFactoryImpl@7b913ed5

      14:35:10,786 INFO     MDB:constructor():  svrSendQueue looked up

      14:35:10,787 INFO                      :     HornetQQueue[goSvrSendQueue]

      14:35:10,787 INFO     MDB:constructor():  svrTestQueue injected

      14:35:10,787 INFO                      :     null

      14:35:10,787 INFO     MDB:constructor():  svrSendQueue cast to Destination

      14:35:10,788 INFO     MDB:constructor():  Session instantiated

      14:35:10,788 INFO                      :     org.hornetq.ra.HornetQRASession@71b4fc0f

      14:35:10,789 INFO     MDB:constructor():  Producer instantiated

      14:35:10,789 INFO                      : org.hornetq.ra.HornetQRAMessageProducer@3a03782

        • 1. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
          Jay SenSharma Master

          That does not look like a problem with the @Resource injection. Rather it looks like the problem is that inside the Constructor you are trying to do it

           

          What to do?

          -----------------

          Can you please try it as following put the following line of code inside the "@PostConstruct" method and remove it from the  "JmsTestMsgBean" Constructor. As there it will be always "null" it is not yet injected.

           

                System.out.print("\n  MDB:constructor():  svrTestQueue injected");
                System.out.print("\n                   :     " + this.svrTestQueue);
          
          

           

           

           

          Please try the following kind of code:

           

          package ejb30;
          import javax.ejb.MessageDriven;
          import javax.jms.JMSException;
          import javax.jms.*;
          import javax.jms.MessageListener;
          import javax.jms.TextMessage;
          import javax.ejb.ActivationConfigProperty;
          import javax.naming.*;
          import javax.sql.DataSource;
          import javax.annotation.*;
          
          
          @MessageDriven(
            activationConfig ={
              @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
              @ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),
              @ActivationConfigProperty(propertyName="destination", propertyValue="jms/goSvrSendQueue")},
              mappedName = "JmsTestMsgBean")
          
          
          
          public class JmsTestMsgBean implements MessageListener{
          
          
            @Resource(name = "java:jboss/exported/jms/goSvrTestQueue")
            private Queue svrTestQueue;
          
          
            private Connection      connection         = null;
            private Session         session            = null;
            private Queue           svrSendQueue       = null;
            private Destination     sendToDestination  = null;
            private MessageProducer msgProducer        = null;
            private final String    jmsSelectorKey     = "MyMessages";
          
            // 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                   :     "+ ctx);
             
                ConnectionFactory factory = (ConnectionFactory) ctx.lookup("java:/jboss/DefaultJMSConnectionFactory");
                System.out.print("\n  MDB:constructor():  Connection Factory looked up");
                System.out.print("\n                   :     " + factory);
             
                this.connection = factory.createConnection("jmsuser", "jmsuser@123");
                System.out.print("\n  MDB:constructor():  Connection established");
                System.out.print("\n                   :     " + this.connection);
             
                this.svrSendQueue = (Queue) ctx.lookup("jboss/exported/jms/goSvrSendQueue");
                System.out.print("\n  MDB:constructor():  svrSendQueue looked up");
                System.out.print("\n                   :     " + this.svrSendQueue);
          
          
               // *****  COMMENTED BELOW because i would do it inside the @PostConstruct instead. *****
               // System.out.print("\n  MDB:constructor():  svrTestQueue injected");
               // System.out.print("\n                   :     " + this.svrTestQueue);
            
                this.sendToDestination = (Destination) this.svrSendQueue;
                System.out.print("\n  MDB:constructor():  svrSendQueue cast to Destination");
             
                this.session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                System.out.print("\n  MDB:constructor():  Session instantiated");
                System.out.print("\n                   :     " + this.session);
          
                this.msgProducer = session.createProducer(sendToDestination);
                System.out.print("\n  MDB:constructor():  Producer instantiated");
                System.out.print("\n                   :     " + this.msgProducer);
             
                System.out.print("\nMDB:constructor():  end");
              }catch(Exception e) {
                System.out.print("\n  MDB:constructor():  Exception - " + e.getClass().getName());
                System.out.print("\n                   :  msg - " + e.getMessage());
                System.out.print("\n  MDB:constructor():  closeing any connection");
                if(this.connection != null)
                  try {
                    this.connection.close();
                  } catch (JMSException e1) {
                    e1.printStackTrace();
                  }
                System.out.print("\nMDB:constructor(): end - w/Exception");
              }
            }
          
            @PostConstruct
            public void myInit () {
                System.out.print("\n >>>>>>>>>  MDB:myInit()     : Construction completed. called try:#8");
                try {
                   System.out.print("\n  ********** MDB: (@PostConstruct) myInit():  svrTestQueue injected");
                   System.out.print("\n  :" + this.svrTestQueue+ "\t QueueName:   " + svrTestQueue.getQueueName());
                 } catch (Exception e) {
                   e.printStackTrace();
                 }
            }
          
          //PreDestroy (Java EE 6 )
            @PreDestroy// RATHER THAN THROWING JMSEXCEPTION HERE BETTER TO USE try{} catch(){} see : 
            public void myDestroy () throws JMSException {
                System.out.print("\n <<<<<<<<<  MDB:myDestroy()  : called to close any connection");
                  try {
                     if(connection != null) connection.close();
                 } catch (Exception e) {
                   e.printStackTrace();
                 }           
            }
          
            public void onMessage(Message msg) {
              System.out.print("\nMDB:onMessage(): begin");
              try {
                System.out.print("\n  ######### MDB: (onMessage) onMessage():  svrTestQueue injected");
                System.out.print("\n                   :     " + this.svrTestQueue+ "\t QueueName:   " + svrTestQueue.getQueueName());  
          
          
                String textReceived = ((TextMessage)msg).getText();
                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                            *
              *************************************************/
            }
          }
          
          /*
          [standalone@localhost:9990 /] /subsystem=messaging/hornetq-server=default/jms-queue=goSvrSendQueue/:add(entries=["java:/jboss/exported/jms/goSvrSendQueue"],durable=false)
          [standalone@localhost:9990 /] /subsystem=messaging/hornetq-server=default/jms-queue=goSvrReceiveQueue/:add(entries=["java:/jboss/exported/jms/goSvrReceiveQueue"],durable=false)
          [standalone@localhost:9990 /] /subsystem=messaging/hornetq-server=default/jms-queue=goSvrTestQueue/:add(entries=["java:/jboss/exported/jms/goSvrTestQueue"],durable=false)
          [standalone@localhost:9990 /] :reload
          */
          
          



          During Deployment Logging

          ########################

          Now with the above code you should be able to see the following kind of loggins as soon as you deploy the application on WildFly:


          13:00:58,746 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0027: Starting deployment of "MDBApplication.jar" (runtime-name: "MDBApplication.jar")
          13:00:58,956 INFO  [org.jboss.as.ejb3] (MSC service thread 1-3) WFLYEJB0042: Started message driven bean 'JmsTestMsgBean' with 'hornetq-ra.rar' resource adapter
          13:00:58,993 INFO  [stdout] (default-threads - 1)
          13:00:58,995 INFO  [stdout] (default-threads - 1) MDB:constructor():  beg
          13:00:58,995 INFO  [stdout] (default-threads - 1)   MDB:constructor():  obtained InitialContext
          13:00:58,996 INFO  [stdout] (default-threads - 1)                    :     javax.naming.InitialContext@2440531
          13:00:58,996 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection Factory looked up
          13:00:59,064 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) WFLYSRV0010: Deployed "MDBApplication.jar" (runtime-name : "MDBApplication.jar")
          13:00:59,065 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRAConnectionFactoryImpl@52dc83b
          13:00:59,065 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection established
          13:00:59,065 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRASessionFactoryImpl@26747921
          13:00:59,065 INFO  [stdout] (default-threads - 1)   MDB:constructor():  svrSendQueue looked up
          13:00:59,066 INFO  [stdout] (default-threads - 1)                    :     HornetQQueue[goSvrSendQueue]
          13:00:59,066 INFO  [stdout] (default-threads - 1)   MDB:constructor():  svrSendQueue cast to Destination
          13:00:59,066 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Session instantiated
          13:00:59,074 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRASession@3092e682
          13:00:59,074 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Producer instantiated
          13:00:59,075 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRAMessageProducer@1eb53e3e
          13:00:59,083 INFO  [stdout] (default-threads - 1) MDB:constructor():  end
          13:00:59,084 INFO  [stdout] (default-threads - 1) MDB:constructor():  beg
          13:00:59,084 INFO  [stdout] (default-threads - 1)   MDB:constructor():  obtained InitialContext
          13:00:59,084 INFO  [stdout] (default-threads - 1)                    :     javax.naming.InitialContext@56753b8e
          13:00:59,084 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection Factory looked up
          13:00:59,088 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRAConnectionFactoryImpl@52dc83b
          13:00:59,088 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Connection established
          13:00:59,088 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRASessionFactoryImpl@6208a227
          13:00:59,088 INFO  [stdout] (default-threads - 1)   MDB:constructor():  svrSendQueue looked up
          13:00:59,088 INFO  [stdout] (default-threads - 1)                    :     HornetQQueue[goSvrSendQueue]
          13:00:59,088 INFO  [stdout] (default-threads - 1)   MDB:constructor():  svrSendQueue cast to Destination
          13:00:59,089 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Session instantiated
          13:00:59,089 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRASession@9c00cca
          13:00:59,089 INFO  [stdout] (default-threads - 1)   MDB:constructor():  Producer instantiated
          13:00:59,089 INFO  [stdout] (default-threads - 1)                    :     org.hornetq.ra.HornetQRAMessageProducer@7d112e72
          
          

           

           

           

          When first time onMessage() invoked -> Logging

          ##########################################


          13:01:08,997 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:constructor():  end
          13:01:08,997 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:constructor():  beg
          13:01:08,997 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  obtained InitialContext
          13:01:08,998 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     javax.naming.InitialContext@20eb52e9
          13:01:08,998 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  Connection Factory looked up
          13:01:09,007 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     org.hornetq.ra.HornetQRAConnectionFactoryImpl@52dc83b
          13:01:09,007 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  Connection established
          13:01:09,007 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     org.hornetq.ra.HornetQRASessionFactoryImpl@141da6bc
          13:01:09,007 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  svrSendQueue looked up
          13:01:09,008 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     HornetQQueue[goSvrSendQueue]
          13:01:09,008 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  svrSendQueue cast to Destination
          13:01:09,008 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  Session instantiated
          13:01:09,009 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     org.hornetq.ra.HornetQRASession@481d5a5c
          13:01:09,009 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:constructor():  Producer instantiated
          13:01:09,009 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     org.hornetq.ra.HornetQRAMessageProducer@14ae6290
          13:01:09,010 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:constructor():  end
          13:01:09,010 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))  >>>>>>>>>  MDB:myInit()     : Construction completed. called try:#8
          13:01:09,010 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   ********** MDB: (@PostConstruct) myInit():  svrTestQueue injected
          13:01:09,012 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   :HornetQQueue[goSvrTestQueue] QueueName:   goSvrTestQueue
          13:01:09,012 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): begin
          13:01:09,012 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   ######### MDB: (onMessage) onMessage():  svrTestQueue injected
          13:01:09,013 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     HornetQQueue[goSvrTestQueue] QueueName:   goSvrTestQueue
          13:01:09,013 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:onMessage()  :  msg Received - "[ MiddlewareMagic!!! ]1 at Sun Nov 22 13:01:08 IST 2015"
          13:01:09,014 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): end - successfully
          13:01:09,014 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): begin
          13:01:09,015 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   ######### MDB: (onMessage) onMessage():  svrTestQueue injected
          13:01:09,015 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     HornetQQueue[goSvrTestQueue] QueueName:   goSvrTestQueue
          13:01:09,015 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:onMessage()  :  msg Received - "[ MiddlewareMagic!!! ]2 at Sun Nov 22 13:01:08 IST 2015"
          13:01:09,016 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): end - successfully
          13:01:09,016 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): begin
          13:01:09,016 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   ######### MDB: (onMessage) onMessage():  svrTestQueue injected
          13:01:09,017 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     HornetQQueue[goSvrTestQueue] QueueName:   goSvrTestQueue
          13:01:09,017 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:onMessage()  :  msg Received - "[ MiddlewareMagic!!! ]3 at Sun Nov 22 13:01:08 IST 2015"
          13:01:09,018 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): end - successfully
          13:01:09,018 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): begin
          13:01:09,019 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   ######### MDB: (onMessage) onMessage():  svrTestQueue injected
          13:01:09,019 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     HornetQQueue[goSvrTestQueue] QueueName:   goSvrTestQueue
          13:01:09,019 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:onMessage()  :  msg Received - "[ MiddlewareMagic!!! ]4 at Sun Nov 22 13:01:08 IST 2015"
          13:01:09,020 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): end - successfully
          13:01:09,020 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942)) MDB:onMessage(): begin
          13:01:09,020 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   ######### MDB: (onMessage) onMessage():  svrTestQueue injected
          13:01:09,020 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))                    :     HornetQQueue[goSvrTestQueue] QueueName:   goSvrTestQueue
          13:01:09,020 INFO  [stdout] (Thread-1 (HornetQ-client-global-threads-560908942))   MDB:onMessage()  :  msg Received - "[ MiddlewareMagic!!! ]5 at Sun Nov 22 13:01:08 IST 2015"
          
          

           

           

           

          Regards

          Jay SenSharma

          • 2. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
            George Berish Novice

            That worked great.

            For  anyone following I just gave up trying combinations of JNDI names without adding the "java:" prefix in my list of original tries.

             

            [One minor change.  In @MessageDriven I changed the queue the the MDB listens to from goSvrSendQueue to goSvrReceive because the MDB is paired with a standalone Java client.  Client sends to goSvrReceiveQueue.  MDB replys using goSvrSendQueue.

             

             

            And once I had this.svrSendQueue injected, I restored the old code that used JNDI to create the Connection, Session, and Producer.  And that worked, i.e. java client that initiated the message received a reply from the MDB.

             

            Note:

            I next tried adding the next step from the tutorial in the link I mentioned above:

            @Inject

              JMSContext jmsCtx;

            That would let me eliminate all JNDI lookups.  But when I put a printlin() statement in onMessage() it said jmsCtx was null.

             

            I'm guessing  it has  something to do with the additional deployment descriptor mentioned in the link:

            <dependency>

             

                <groupId>org.jboss.spec.javax.jms</groupId>

                <artifactId>jboss-jms-api_2.0_spec</artifactId>

                <version>1.0.0.Alpha1</version>

            </dependency>

             

            I'm just not sure which data descriptor contains those tags.  I assume that won't be hard to find.  But if not, I think things like that are supposed to be posted as a separate new question anyway.  But once that works I'll clean everything up and post the MDB and its companion standalone java client as a discussion instead of a question. (grin  or as a question if I can't figure it out.)

             

            Your input has been very valuable, much appreciated and I'm sure will help a lot of beginners. Thanks.

            • 3. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
              Jay SenSharma Master

              You said:

              @Inject
                JMSContext jmsCtx;
              That would let me eliminate all JNDI lookups.  But when I put a printlin() statement in onMessage() it said jmsCtx was null.
              
              

               

              Are you adding the "META-INF/beans.xml" inside your EJB jar   (In case of WAR it can be placed inside the "WEB-INF/beans.xml") ?

              An application that uses CDI must have a file named beans.xml. The file can be completely empty (it has content only in certain limited situations), but it must be present. For a web application, the beans.xml file must be in the WEB-INF directory. For EJB modules or JAR files, the beans.xml file must be in the META-INF directory.

               

              Example:

               

              <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="
                    http://java.sun.com/xml/ns/javaee 
                    http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
              </beans>
              
              

               

              Please see: wildfly-quickstart/beans.xml at master · sgilda/wildfly-quickstart · GitHub

              • 4. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                Justin Bertram Master

                I'm guessing  it has  something to do with the additional deployment descriptor mentioned in the link:

                <dependency>

                 

                    <groupId>org.jboss.spec.javax.jms</groupId>

                    <artifactId>jboss-jms-api_2.0_spec</artifactId>

                    <version>1.0.0.Alpha1</version>

                </dependency>

                 

                I'm just not sure which data descriptor contains those tags.  I assume that won't be hard to find.  But if not, I think things like that are supposed to be posted as a separate new question anyway.  But once that works I'll clean everything up and post the MDB and its companion standalone java client as a discussion instead of a question. (grin  or as a question if I can't figure it out.)

                This is a dependency declaration for the project's pom.xml which is a Maven file.  It doesn't go into your deployment.  If you want to Mavenize your project then you should read some Maven tutorials.

                • 5. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                  George Berish Novice

                  Thanks for the clarification.  When I tried to inject the jmsContext, I was responding to a suggestion you offered on another question where I thought you said I could eliminate the need for my MDB to explicitily  instantiate a Connection, Session, Producer.  In that suggestion you also provided the the link I put at the start of my above question.  I didn't realize that the suggested simplification required I Mavinize, which was never my intent.  So based on your clarification, I'll just stay with a standard old JMS approach that works.  Mavin sounds great, but for now plain vanilla use of WildFly is more than enough.

                  • 6. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                    Justin Bertram Master

                    I didn't realize that the suggested simplification required I Mavinize, which was never my intent.

                    You don't need to use Maven in order to inject a JMSContext into your MDB.  You can, in fact, eliminate the need to instantiate the Connection, Session, and Producer by injecting a JMSContext and you don't need Maven to do it.

                     

                    Maven is an extremely popular tool for managing and building Java projects and so many authors will include details on how their tutorials fit with Maven since it's more than likely their readers will be using it to build their projects.  However, this doesn't mean that Maven is required for the Java code to compile and run as advertised.  Maven has a powerful and fairly simple dependency management feature that takes away some of the traditional classpath head-aches found in many Java projects.  The <dependency> definition found in the linked tutorial is simply informing the reader how they can get all the necessary jars into their project, nothing more.

                     

                    Lastly, if it hasn't been made clear already, the tool is called Maven and not Mavin.

                    • 7. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                      George Berish Novice

                      Justin, thanks for the clarification.

                       

                      But I guess I'm now back where I began with a JMSContext.

                      I have a MDB that works fine with regular JNDI lookups.

                      I tried injecting JMSContext as shown in the link you provided earlier:

                       

                      public class JmsTestMsgBean implements MessageListener{

                        @Inject

                        JMSContext jmsCtx;

                       

                      But in @postConstruct I found jmsCtx is null.

                       

                      So I first thought the deployment code at the bottom of the link might have something to do with that failure.  But as you pointed out, that code is only relevant when Maven is involved (sorry about the spelling) and it is not.

                       

                      So now I know it is not relevant, I can't see anything else in the link that would help me, so I'll just stay with the less elegant JNDI lookup approach. [Unless you can point out something else I'm overlooking.]

                       

                      ---------------------------------------------------------------

                      Otherwise Happy Thanksgiving to all,

                      I'm sure this forum is something all WildFly beginners are thankful for.

                      I am.

                      • 8. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                        Jay SenSharma Master

                        Looks like the container will not inject the dependencies in MDB by default. So try adding the "@javax.enterprise.context.ApplicationScoped" annotation to at the MDB class level, then i guess the JMSContext will be injected successfully.


                        Example:


                        import javax.inject.*;
                        import javax.jms.JMSContext;
                        import javax.enterprise.context.ApplicationScoped;
                        
                        @MessageDriven(
                          activationConfig ={
                            @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
                            @ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),
                            @ActivationConfigProperty(propertyName="destination", propertyValue="java:jboss/jms/goSvrReceiveQueue")},
                            mappedName = "JmsTestMsgBean")
                        
                        
                        @ApplicationScoped      // *** NOTICE ***
                        public class JmsTestMsgBean implements MessageListener{
                        
                          @Inject
                          private JMSContext context;
                        .
                        .
                        .
                          @PostConstruct
                          public void myInit () {
                            System.out.print("\nMDB:myInit(): completed. called try:#8");
                            System.out.println("\n\t &&&&&&&&&& GOT jmsContext: " + context);     //  -> See here
                          }
                        .
                        .
                        }
                        
                        • 9. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                          George Berish Novice

                          Jay,

                          As always, your solution above is correct.  Annotating the class with @ApplicationScoped made @inject JMSContext jmsCtx; work.

                           

                          For others here's the other things from the beginning:

                           

                          -- Realizing injected resources were not available until after the constructor is completed.

                           

                          -- DO NOT attempt to close the JMS connections in the MDB. It's good practice for the standalone client to close any Connections it starts.  But I guess the multiple instances of the MDB in the pool share resources like a Connection. So it's best to let the container deal with it.

                           

                          -- Adding a Runnable to stall completion of the client's main() method till onMessage() received the reply was needed.  Otherwise every run of main() sent a new message and picked up the OLD one. (So I made JmsTestClient.p() add the Thread name to the printlin() output in the console, since I'm not good with threads.)

                           

                          Taken all together I now have what I needed as a beginner:

                          -- A standalone java client, and

                          -- A WildFly-deployed MessageDrivenBean

                          That successfully swap messages. 

                           

                          [If anyone could tell me how to stop the extra output being feed into the err print stream of the ECLIPSE CONSOLE OUTPUT (below) I'd appreciate it).

                           

                          Items pasted below:

                          -- ECLIPSE CONSOLE OUTPUT

                          -- WILDFLY SERVER LOG (extract off lines printed by MDB)

                          -- STANDALONE CLIENT

                          -- MDB

                          -- ADDITION TO standalone-full.xml (MDB Send and Receive Queues)

                          -- application.xml

                          -------------------------------

                          -- ECLIPSE CONSOLE OUTPUT

                          [Thread=main]  main() : begin

                          [Thread=main]    constructor() :  begin

                          Nov 29, 2015 1:47:53 PM org.xnio.Xnio <clinit>

                          INFO: XNIO version 3.3.1.Final

                          Nov 29, 2015 1:47:53 PM org.xnio.nio.NioXnio <clinit>

                          INFO: XNIO NIO Implementation Version 3.3.1.Final

                          Nov 29, 2015 1:47:53 PM org.jboss.remoting3.EndpointImpl <clinit>

                          INFO: JBoss Remoting version 4.0.9.Final

                          [Thread=main]      constructor() :  JNDI Context:

                                               javax.naming.InitialContext@1f021e6c

                          Nov 29, 2015 1:47:54 PM org.jboss.ejb.client.remoting.VersionReceiver handleMessage

                          INFO: EJBCLIENT000017: Received server version 2 and marshalling strategies [river]

                          Nov 29, 2015 1:47:54 PM org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate

                          INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@4c6e276e, receiver=Remoting connection EJB receiver [connection=Remoting connection <4de8ae43>,channel=jboss.ejb,nodename=ace]} on channel Channel ID cfbd4b9e (outbound) of Remoting connection 0e50a6f6 to localhost/127.0.0.1:8080

                          Nov 29, 2015 1:47:54 PM org.jboss.ejb.client.EJBClient <clinit>

                          INFO: JBoss EJB Client version 2.1.1.Final

                          [Thread=main]      constructor() :  JMS Connection :

                                               org.hornetq.jms.client.HornetQConnection@29d89d5d

                          [Thread=main]      constructor() :  JMS Session :

                                               HornetQSession->DelegatingSession

                                               ...

                          [Thread=main]      constructor() :  MessageProducer:

                                               org.hornetq.core.client.impl.ClientProducerImpl

                          [Thread=main]      constructor() :  MessageConsumer:

                                               ...

                                               org.hornetq.core.client.impl.ClientConsumerImpl

                          [Thread=main]      constructor() :  setting client as message listener

                          [Thread=main]    constructor() :  end

                          [Thread=main]    main() : msg sent date:  2015-11-29 13:47:52.989

                          [Thread=main]    main() : loop #0

                          [Thread=main]    main() : new Sleeper thread instantated as thread sleeper_0

                          [Thread=main]    main() : starting thread to block main threadsleeper_0

                          [Thread=sleeper_0]  run() : begin

                          [Thread=sleeper_0]    run() : Sleeper nodding off for 1000 ms

                           

                          #The following onMessage() output was all run from a thread named:

                          # "Thread-0 (HornetQ-client-global-threads-1453774246)"

                          # I substitured "HQ" for it below

                          [Thread=]  onMessage() : begin

                          [Thread=HQ]    onMessage() :  reply received

                          [Thread=HQ]    onMessage() :    text object     - "Hi. Received your message ok."

                          [Thread=HQ]    onMessage() :    originally sent - 2015-11-29 13:47:52.989

                          [Thread=HQ]  onMessage() : end

                           

                          [Thread=sleeper_0]    run() :  Sleeper waking up

                          [Thread=sleeper_0]  run() : end

                          [Thread=main]    main() : join() expired. main thread resuming.

                          [Thread=main]    main() : reply message was received

                          [Thread=main]    main() : interrupt t. break loop

                          [Thread=main]  main() : end

                           

                          -- WILDFLY SERVER LOG (Extract of output printed from my MDB)

                          ...

                          =============================================

                          13:45:35,961 INFO  (main) JBoss Modules version 1.4.3.Final

                          13:45:36,305 INFO  (main) JBoss MSC version 1.2.6.Final

                          13:45:36,403 INFO  WFLYSRV0049: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) starting

                          ...

                          13:45:40,164 INFO  HQ221003: trying to deploy queue jms.queue.goSvrSendQueue

                          13:45:40,171 INFO  HQ221003: trying to deploy queue jms.queue.goSvrReceiveQueue

                          ...

                          13:45:41,172 INFO  WFLYSRV0010: Deployed "jmsTest.ear" (runtime-name : "jmsTest.ear")

                          ...

                          13:45:41,304 INFO  WFLYSRV0025: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) started in 5929ms

                          ...

                          #From here down I replaced

                          #"(Thread-1 (HornetQ-client-global-threads-1145696399))"

                          #with

                          #"(Thread-1)"

                          13:46:05,046 INFO  (Thread-1)

                          13:46:05,047 INFO  (Thread-1) MDB:postConstruction()  : begin

                          13:46:05,047 INFO  (Thread-1) MDB:constructor()  :  found svrSendQueue

                          13:46:05,047 INFO  (Thread-1)                      :     HornetQQueue[goSvrSendQueue]

                          13:46:05,049 INFO  (Thread-1) MDB:postConstruction()   :  end

                          13:46:05,049 INFO  (Thread-1)

                          13:46:05,050 INFO  (Thread-1) MDB:onMessage()  : begin

                          13:46:05,053 INFO  (Thread-1) MDB:onMessage()  :  msg Received

                          13:46:05,053 INFO  (Thread-1) MDB:onMessage()  :    text - "Please Send a Reply"

                          13:46:05,091 INFO  (Thread-1) MDB:onMessage()  :    sent - "2015-11-29 13:46:02.645"

                          13:46:05,094 INFO  (Thread-1) MDB:onMessage()  :  reply message created

                          13:46:05,094 INFO  (Thread-1) MDB:onMessage()  :  set Object to string

                          13:46:05,095 INFO  (Thread-1)                    :     "Hi. Received your message ok."

                          13:46:05,095 INFO  (Thread-1) MDB:onMessage()  :  set message property

                          13:46:05,095 INFO  (Thread-1)                    :    Key : "dateKey"

                          13:46:05,096 INFO  (Thread-1)                    :    Value: "2015-11-29 13:46:02.645"

                          13:46:05,096 INFO  (Thread-1) MDB:onMessage()  :  setting selector property

                          13:46:05,096 INFO  (Thread-1)                    :  Key

                          13:46:05,096 INFO  (Thread-1)                    :     "MyMessages"

                          13:46:05,097 INFO  (Thread-1)                    :  Value

                          13:46:05,105 INFO  (Thread-1)                    : "w3Mij#l4"

                          13:46:05,105 INFO  (Thread-1) MDB:onMessage()  :  message sent

                          13:47:54,707 INFO  (Thread-1) MDB:onMessage(): end - successfully

                          13:47:54,707 INFO  (Thread-1)

                          13:47:54,708 INFO  (Thread-1) MDB:onMessage()  : begin

                          13:47:54,708 INFO  (Thread-1) MDB:onMessage()  :  msg Received

                          13:47:54,708 INFO  (Thread-1) MDB:onMessage()  :    text - "Please Send a Reply"

                          13:47:54,711 INFO  (Thread-1) MDB:onMessage()  :    sent - "2015-11-29 13:47:52.989"

                          13:47:54,711 INFO  (Thread-1) MDB:onMessage()  :  reply message created

                          13:47:54,712 INFO  (Thread-1) MDB:onMessage()  :  set Object to string

                          13:47:54,712 INFO  (Thread-1)                    :     "Hi. Received your message ok."

                          13:47:54,712 INFO  (Thread-1) MDB:onMessage()  :  set message property

                          13:47:54,712 INFO  (Thread-1)                    :    Key : "dateKey"

                          13:47:54,712 INFO  (Thread-1)                    :    Value: "2015-11-29 13:47:52.989"

                          13:47:54,713 INFO  (Thread-1) MDB:onMessage()  :  setting selector property

                          13:47:54,713 INFO  (Thread-1)                    :  Key

                          13:47:54,713 INFO  (Thread-1)                    :     "MyMessages"

                          13:47:54,713 INFO  (Thread-1)                    :  Value

                          13:47:54,714 INFO  (Thread-1)                    :     "w3Mij#l4"

                          13:47:54,715 INFO  (Thread-1) MDB:onMessage()  :  message sent

                           

                          -- STANDALONE CLIENT

                          package org.america3.gotest.client;

                          import java.sql.Timestamp;

                          import java.util.Properties;

                          import javax.jms.*;

                          import javax.naming.*;

                          import org.hornetq.jms.client.HornetQJMSConnectionFactory;

                           

                          /**

                          * Required jars

                          * 1. jboss-client.jar:                               

                          * <JBOSS_HOME>\bin\client                                  

                          * 2. hornetq-jms-client-2.4.7.Final.jar              

                          * <JBOSS_HOME>\modules\system\layers\base\org\hornetq\main\

                          */

                           

                          public class JmsTestClient implements MessageListener {

                            /*

                             * these are the properties required to secure an

                             * InitialContext() from WIldFly by a standalone Java Client

                             */

                            final private Properties env = new Properties() {

                              private static final long serialVersionUID = 1L;

                              {

                                put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); 

                                put(Context.PROVIDER_URL, "http-remoting://localhost:8080");

                                put(Context.SECURITY_PRINCIPAL, "jmsuser"); 

                                put(Context.SECURITY_CREDENTIALS, "jmsuser@123"); 

                          put("jboss.naming.client.ejb.context", true); 

                              }

                            };

                           

                             private Connection      jmsConnection           = null;

                             private MessageProducer jmsMsgProducer          = null;

                             private MessageConsumer jmsMsgConsumer          = null;

                             private ObjectMessage   objMsg                  = null;

                             private String          sendingDate             = new Timestamp((new java.util.Date()).getTime()).toString();

                             private boolean         replyReceived           = false;

                             // following class member makes nap time easy to change

                             private int             napFor                  = 1000;

                            

                             private final String jmsSelectorKey   = "MyMessages";

                             private final String jmsSelectorValue = "w3Mij#l4";

                             private final String jmsSelector      = jmsSelectorKey + "=\'" + jmsSelectorValue + "\'";

                           

                             /*

                              * the following is so I could be sure the reply received was the

                              * to the message just sent, and not from a prior test run

                              */

                             static private final String dateSentKey      = "dateKey";   

                           

                             //constructor

                             private JmsTestClient (){

                               JmsTestClient.p("  constructor() :  begin");

                               try {

                                 // injection is not available to client. Had to use JNDI lookup.

                                 Context ctx = new InitialContext(this.env);

                                 JmsTestClient.p("    constructor() :  JNDI Context: " + ctx);

                                

                                 HornetQJMSConnectionFactory jmsConnectionFactory = (HornetQJMSConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");

                                 this.jmsConnection = jmsConnectionFactory.createConnection("jmsuser", "jmsuser@123");

                                 this.jmsConnection.start();

                                 JmsTestClient.p("    constructor() :  JMS Connection : " + this.jmsConnection);

                                

                                 Session jmsSession = this.jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                                 JmsTestClient.p("    constructor() :  JMS Session : " + jmsSession);

                                

                                 // create MessageProducer

                                 Queue jmsSendToQueue = (Queue) ctx.lookup("jms/goSvrReceiveQueue");

                                 this.jmsMsgProducer = jmsSession.createProducer(jmsSendToQueue);

                                 JmsTestClient.p("    constructor() :  MessageProducer: " + this.jmsMsgProducer);

                                

                                 // create MessageConsumer

                                 Queue jmsReceiveFmQueue = (Queue) ctx.lookup("jms/goSvrSendQueue");

                                 this.jmsMsgConsumer = jmsSession.createConsumer(jmsReceiveFmQueue, jmsSelector);

                                 JmsTestClient.p("    constructor() :  MessageConsumer: " + this.jmsMsgConsumer);

                           

                                 JmsTestClient.p("    constructor() :  setting client as message listener");

                          this.jmsMsgConsumer.setMessageListener(this);

                                

                                 this.objMsg = jmsSession.createObjectMessage();

                                 JmsTestClient.p("constructor() :  end");

                               } catch (CommunicationException e) {

                                 JmsTestClient.p ("  constructor() :  You forgot to start WildFly dummy!");      

                               } catch (Exception e) {

                                 JmsTestClient.p ("  constructor() :  caught: " + e.getClass().getName());

                                 JmsTestClient.p("                     :  " + e.getMessage());

                               }

                             }

                            

                            static public void main (String[] args) {

                              JmsTestClient.p("main() :  begin");

                              JmsTestClient client = new JmsTestClient(); // to make available in catch block

                              try {

                                client.objMsg.setObject(new String("Please Send a Reply"));

                          client.objMsg.setStringProperty(client.jmsSelectorKey, client.jmsSelectorValue );

                          client.objMsg.setStringProperty(dateSentKey, client.sendingDate);

                                client.jmsMsgProducer.send(client.objMsg);         

                                JmsTestClient.p("  main() : msg sent date:  " + client.sendingDate);

                                /*

                                 * initially main() would always receive the reply to the message

                                 * sent by the client the LAST time main() was run.

                                 * I had to block completion of main() till it onMessage() had time

                                 * to receive the reply.

                                 * In actual application, client will be a java GUI

                                 * that stays open anyway.  Here I just use Runnable Sleeper to block

                                 * the main thread for awhile and it seemed to work. See console ouput.

                                 */

                                int indx    = 0;

                                int indxMax = 1;

                                while (indx < indxMax) {

                                  JmsTestClient.p("  main() : loop #"+indx);

                                  if(client.replyReceived) {

                                    JmsTestClient.p("  main() : message received.  end loop.  indx = " + indx);

                                    break;

                                  }

                                  Thread t = new Thread(client.new Sleeper(),"sleeper_" + String.valueOf(indx));

                                  JmsTestClient.p("  main() : new Sleeper thread instantated as thread " + t.getName());

                                  JmsTestClient.p("  main() : starting thread to block main thread" + t.getName());

                                  t.start(); // t will run, then nap for the value of client.napFor ms.

                                  t.join();  // main thread will be blocked while Sleeper naps

                                  JmsTestClient.p("  main() : join() expired. main thread resuming.");

                                 

                                  if (client.replyReceived) {

                                    JmsTestClient.p("  main() : reply message was received");

                                    JmsTestClient.p("  main() : interrupt t. break loop");

                                    t.interrupt();

                                    break;

                                  } else {

                                    // no reply received.

                                    JmsTestClient.p("  main() : no message yet. loop again");

                                  }

                                  indx++;

                                }

                                if (client.jmsConnection != null) client.jmsConnection.close();

                                JmsTestClient.p("main() :  end");

                              } catch (Exception e) {

                                JmsTestClient.p("  main() : caught " + e.getClass().getName());     

                                JmsTestClient.p("  main() : " + e.getMessage());     

                                JmsTestClient.p("main() :  end");

                              }

                            }

                           

                            public void onMessage(Message msg) {

                              JmsTestClient.p("onMessage() :  begin");

                              try {

                                String dateItWasSent = (String)(msg.getStringProperty(dateSentKey));

                                JmsTestClient.p("  onMessage() : reply received");

                                this.replyReceived = true;

                                JmsTestClient.p("  onMessage() :    text object     - \"" + (String)((ObjectMessage)msg).getObject() + "\"");

                                JmsTestClient.p("  onMessage() :    originally sent - " + dateItWasSent);

                                JmsTestClient.p("onMessage() :  end");

                              } catch (JMSException e) {

                                JmsTestClient.p("  onMessage() : caught " + e.getClass().getName());     

                                JmsTestClient.p("  onMessage() :  " + e.getMessage());     

                                JmsTestClient.p("main() :  end stacktrace follows:");

                                e.printStackTrace();

                              }

                            }

                           

                            // inner class

                            class Sleeper implements Runnable {

                              public void run() {

                                JmsTestClient.p("run() :  begin");

                                try {

                                 JmsTestClient.p("run() : Sleeper nodding off for " + napFor + " ms");

                                 Thread.sleep(1000);

                                 JmsTestClient.p("Sleeper waking up");

                                 JmsTestClient.p("run() :  end");

                               } catch (InterruptedException e) {

                                 JmsTestClient.p("  run() : caught " + e.getClass().getName());     

                                 JmsTestClient.p("  run() : " + e.getMessage());     

                               }

                              }

                            }

                            

                            static private void p (String s) {

                              String threadName = "[Thread=" + Thread.currentThread().getName() + "] ";

                              System.out.println(threadName + s);

                            }

                          }

                           

                          -- MDB

                          package org.america3.gotest.server.messaging;

                           

                          import javax.ejb.MessageDriven;

                          import javax.inject.Inject;

                          import javax.jms.*;

                          import javax.ejb.ActivationConfigProperty; 

                          import javax.naming.*; 

                          import javax.annotation.*; 

                          import javax.enterprise.context.ApplicationScoped;

                           

                          @MessageDriven( 

                            activationConfig ={ 

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

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

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

                              mappedName = "JmsTestMsgBean") 

                           

                          public class JmsTestMsgBean implements MessageListener{

                           

                            @ApplicationScoped

                            @Inject

                            JMSContext jmsCtx;

                           

                            @Resource(name = "java:/jboss/exported/jms/goSvrSendQueue") 

                            private Queue svrSendQueue; 

                           

                            static private final String dateSentKey      = "dateKey";

                            private final String      jmsSelectorKey     = "MyMessages"; 

                            private final String      jmsSelectorValue   = "w3Mij#l4";

                             

                            @PostConstruct 

                            public void postConstruction () throws NamingException { 

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

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

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

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

                            } 

                           

                            @PreDestroy

                            public void myDestroy () { 

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

                              System.out.print("\n  MDB:myDestroy()  : not used");

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

                            } 

                           

                            public void onMessage(Message msg) { 

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

                              try {

                                String dateSent = msg.getStringProperty(dateSentKey);

                                ObjectMessage receivedMsg = (ObjectMessage) msg;

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

                                System.out.print("\n  MDB:onMessage()  : text - \"" + ((String)receivedMsg.getObject()) + "\""); 

                                System.out.print("\n  MDB:onMessage()  : sent - \"" + dateSent + "\""); 

                           

                                ObjectMessage replyMsg = jmsCtx.createObjectMessage();

                                System.out.print("\n  MDB:onMessage()  : reply message created");

                           

                                replyMsg.setObject(new String("Hi. Received your message ok."));

                                System.out.print("\n  MDB:onMessage()  :  set Object to string");

                                System.out.print("\n                   :     \"Hi. Received your message ok.\"");

                           

                          replyMsg.setStringProperty(dateSentKey,dateSent);

                                System.out.print("\n  MDB:onMessage()  :  set message property");

                                System.out.print("\n                   :    Key : \"" + dateSentKey + "\"");

                                System.out.print("\n                   :    Value: \"" + dateSent + "\"");

                               

                          replyMsg.setStringProperty(this.jmsSelectorKey, jmsSelectorValue);     

                                System.out.print("\n  MDB:onMessage()  : setting selector property");

                                System.out.print("\n                   :  Key");

                                System.out.print("\n                   :     \"" + this.jmsSelectorKey + "\"");

                                System.out.print("\n                   :  Value");

                                System.out.print("\n                   :     \"" + jmsSelectorValue + "\"");

                            

                          this.jmsCtx.createProducer().send(this.svrSendQueue, replyMsg);

                                System.out.print("\n  MDB:onMessage()  : message sent");

                               

                                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"); 

                                //jmsCtx.close(); 

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

                              } 

                            } 

                           

                          -- ADDITION TO standalone-full.xml (MDB Send and Receive Queues)

                          <jms-destinations>

                          ...

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

                          ...

                          </jms-destinations>

                           

                          -- application.xml

                          <?xml version="1.0" encoding="UTF-8"?> 

                            <application 

                              xmlns="http://java.sun.com/xml/ns/j2ee" 

                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

                              xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" 

                              version="1.4"> 

                              

                              <description>GoTest</description> 

                              <display-name>JmsTestMsgBean</display-name> 

                              <module>

                                <ejb>jmsTest.jar</ejb> 

                              </module>

                            </application>

                          • 10. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                            Justin Bertram Master

                            -- DO NOT attempt to close the JMS connections in the MDB. It's good practice for the standalone client to close any Connections it starts.  But I guess the multiple instances of the MDB in the pool share resources like a Connection. So it's best to let the container deal with it.

                            This is a bit misleading since if you inject a JMSContext object (as you are doing) then you don't even see the JMS connection and session objects.  The JMSContext injected by the container hides the underlying connection and session objects to simplify the API.

                             

                            Furthermore, if you didn't inject a JMSContext and rather followed the traditional JMS pattern (i.e. JNDI lookup for connection factory, create connection, create session, etc.) then best practice dictates that you should in fact close the connection because you should be using a pooled connection factory and closing the connection would return the connection to the pool for other components to use.

                             

                            -- Adding a Runnable to stall completion of the client's main() method till onMessage() received the reply was needed.  Otherwise every run of main() sent a new message and picked up the OLD one. (So I made JmsTestClient.p() add the Thread name to the printlin() output in the console, since I'm not good with threads.)

                            I think you could do what you want much more easily with a CountDownLatch.

                             

                            Also, the typical JMS request/response pattern uses the JMSCorrelationID header field to link the reply with the request so the consumer can be sure it's getting the proper reply.

                            • 11. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                              George Berish Novice

                              Jay,

                               

                              Thank you for the pointers. But I'm not advanced enough yet to usefully sort it out. 


                              My comment was the result of a solution provided to an earlier problem when I was using JNDI lookup to implement JMS in my MDB.

                               

                              https://developer.jboss.org/message/946315?et=watches.email.thread#946315

                              Why does my MessageDrivenBean JMS Session close by itself? Can/shouldn't it remain open?

                               

                              With that approach my client worked once, and then failed on the second try.

                              The problem was I was closing the connection.

                              The solution was to not close it.

                               

                              Now based on your comments I guess the problem was I was closing the connection in the wrong method.

                               

                              I guess it should have only been done in the PreDestroy method.  But I had it it in all the Exception catch blocks, so when one message had an error it closed the connection of the MDB without taking the MDB out of the pool.  But I'm just guessing.

                               

                              Regardless ... as you point out, now that I have injection working there's no need to worry about it.

                               

                              And thank you for the recommendation about using JMSCorrelationID, but right now I'm on new-stuff-overload, so I'd like to just master plain old vanilla Java.   And for my purposes JMS message selectors seem adequate.

                               

                              Each time another client opens it creates a random string as its selector.  The client adds it to every message it sends.  The MDB carries it forward in its reply.  The Queue delivers messages to their originating client..

                              • 12. Re: Why does JNDI lookup work in my MDB, but @Resource fail?
                                Justin Bertram Master

                                My comment was the result of a solution provided to an earlier problem when I was using JNDI lookup to implement JMS in my MDB.

                                Yes, I know.  I believe I was the one that pointed our the mistake in your code.

                                 

                                With that approach my client worked once, and then failed on the second try.

                                The problem was I was closing the connection.

                                The solution was to not close it.

                                 

                                Now based on your comments I guess the problem was I was closing the connection in the wrong method.

                                The problem wasn't that you were closing the connection in the wrong method.  The problem is that you were only opening the connection once instead of each time you needed it.  But I digress...

                                 

                                As you said, since you're using injection it doesn't really matter at this point.