4 Replies Latest reply on Nov 21, 2015 5:03 PM by George Berish

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

    George Berish Novice

      I'm a refugee from GlassFish learning WildFly.  I need a cut-and-paste example of a standalone Java Client able to swap JMS messages with a MessageDrivenBean, but there are none, so I'm making it. So far I have a client-MDB pair that almost work. 

       

      First time I run the client, it works.  The MDB onMessage() method receives the clients message.  It sends a reply to another Queue to which the client listens. The client retreives it.

       

      But second time I run the cleint, it fails on the server side.  The client sends a message.  The MDB onMessage() method receives it.  Then the MDB throws an IllegalStateException because the session it uses was closed.

       

      I though the idea with JMS was to re-use objects like Session.  So I instantiated the session as class member in the MDB constructor which I thought would make it a permanent part of the MDB instance unless the server shut down. 

       

      I'm obviously lost.  Any explanation or help is appreciated.

       

      I put everything below.  Hope it's not too much, but I though it might help anyone else new to WildFly.  With two additions, cutting and pasting the code should work with an out of the box WildFly running on localhost:  1) add a new user (role: "guest";  name:" jmsuser";  pw:" jmsuser@123"), and 2) add  two Queues in the standalone.xml as shown below.]

       

      Here's what follows:

      1. 1.  MDB Code:
      2. 2.  Client Code:
      3. 3.  application.xml
      4. 4.  xml added to standalone-full.xml for Queues
      5. 5.  Structure of jmsTest.ear file used to autodeploy MDB
      6. 6. Minimized extract from WildFly server.log covering a) Start up with jmsTest.ear stored in <WILDFLY_HOME>/standalone/deployments, b) client run successfully 1st time, then c)client failing on 2nd try.
      7. 7.  Eclipse console printout for successful run.
      8. 8.  Eclipse console printout for failed run.

       

      1. 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 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);

          

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

          if(this.connection != null) this.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()  : 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");

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

          }

          if(connection != null)

            try {

              connection.close();

            } catch (JMSException e) {

              e.printStackTrace();

            }

        }

      }

       

      2. STANDALONE JAVA CLIENT CODE:

      package org.america3.gotest.client;

      ALL IMPORTS

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

      * Required jars                                             *

      * 1. jboss-client.jar found in:                             *

      * <JBOSS_HOME>\bin\client                                   *

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

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

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

       

      public class JmsTestClient implements MessageListener {

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

         * these are properties for JNDI InitialContext(env) used *

         * by stand alone java client run on same computer where  *

         * WildFly is on localhost.                               *

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

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

          }

        };

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

         * Not all these need to be class members.  It just seemed *

         * nice to put them all in one place as an overview.       *

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

        private Context                     ctx                     = null;

        private HornetQJMSConnectionFactory jmsConnectionFactory    = null;

        private Connection                  jmsConnection           = null;

        private Session                     jmsSession              = null;

        private Queue                       jmsReceiveFmQueue       = null;

        private Queue                       jmsSendToQueue          = null;

        private MessageConsumer             jmsMsgConsumer          = null;

        private MessageProducer             jmsMsgProducer          = null;

        private boolean                     msgReturnedFlag         = false;

        private JmsTestClient.KillSomeTime  timeKiller              = null;

        private final String jmsSelectorKey   = "MyMessages";

        private final String jmsSelectorValue = "w3Mij#l4";

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

        

        private JmsTestClient () {

          try {

              p(" constructor() :  selector expression.");

              p("                    " + this.jmsSelector);

            this.ctx = new InitialContext(JmsTestClient.ENV);

              p(" constructor() :  ctx ok");

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

              p(" constructor() :  factory look up ok");

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

              p(" constructor() :  from Queue ok");

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

              p("  constructor() :  send to Queue ok");

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

              p(" constructor() :  connection ok");

            this.jmsConnection.start();

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

              p(" constructor() :  session ok");

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

              p(" constructor() :  consumer ok");

            this.timeKiller = new KillSomeTime ();

              p(" constructor() :  instantiated KillSomeTime Runnable ok");

            this.jmsMsgConsumer.setMessageListener(this);

              p(" constructor() :  listener set ok");

            this.jmsMsgProducer = jmsSession.createProducer(jmsSendToQueue);

              p(" constructor() :  producer ok");

              p("constructor() :  end of constructor ok");

          } catch (CommunicationException e) {

              p ("You forgot to start WildFly dummy!");      

          } catch (Exception e) {

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

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

            if (this.jmsConnection != null)

            try {

              this.jmsConnection.close();

            } catch (JMSException e1) {

              e1.printStackTrace();

            }

          }

        }

        

        static public void main (String[] args) {

          System.out.println("Begin main()");

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

          try {

            ObjectMessage msg = testClient.jmsSession.createObjectMessage();

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

            msg.setStringProperty(testClient.jmsSelectorKey, testClient.jmsSelectorValue );

            testClient.jmsMsgProducer.send(msg);         

            testClient.p("main()        : message sent");

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

             * The rest may be overkill, but it seemed like the main thread*

             * would need some time after it sent a message while it waited*

             * for a reply.  In actual application, client will be a java  *

             * GUI that stays open anyway.                                 *

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

            Thread t = new Thread(testClient.timeKiller);

            testClient.killSomeTime (t);

            if (t.isAlive()) {

              testClient.p("main()        : t.join() timed out. t still running. Interrupt it.");

              t.interrupt();

            }

            Thread.sleep(1000); // give Main thread time to check for calls to onMessage();

            if (testClient.msgReturnedFlag) {

              testClient.p("main()        : ending with message returned."); 

              return;      

            } else {

              testClient.p("main()        : ending with no message returned.");

            }

            try {

              testClient.jmsConnection.close();

            } catch (JMSException e) {

              e.printStackTrace();

            }

          } catch (Exception e) {

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

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

          }

        }

       

        public void onMessage(Message msg) {

          try {

            this.p("Received Message");

            this.p("text: \"" + (String)((ObjectMessage)msg).getObject() + "\"");

          } catch (JMSException e) {

            e.printStackTrace();

          }

          this.msgReturnedFlag = true;

        }

        

        private void killSomeTime (Thread t) {

          t.start();

          try {

            t.join (4000);

            p("killSomeTime(): t.join() timed out.");

          } catch (InterruptedException e) {

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

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

          }

          if (this.msgReturnedFlag) {

            this.p("killSomeTime():  ended with message returned");

          } else {

            p("killSomeTime():  ended w/ no message returned");

          }

        }

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

         * used to kill sometime on a different Thread    *

         * to let the main tread wait for a reply message *

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

        class KillSomeTime implements Runnable {

          public void run() {

            for (int i = 0; i < 8; i++) {

              try {

                Thread.sleep(1000);

                  p("run()       : Yawn #" + i + " any message yet?");

                if (msgReturnedFlag) {

                    p("run()     : yes.  Ok I quit"); 

                  return;

                } else {

                    p("run()       : no.   Ok back to sleep");

                }

              } catch (InterruptedException e) {

                  p("run(): Interrupted: on sleep cycle " + i);

                return;

              }

            }

            p("run(): Done killing time.  Should not have gotten here.");

          }

        }

       

        private void p (String s) {

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

          System.out.println(threadName + s);

        }

      }

       

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

       

      4.  LINES ADDED TO STANDALONE-FULL.XML

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

       

      5.  STRUCTURE OF jmsTest.ear FILE USED TO AUTODEPLOY MDB

        jmsTest.ear

             META-INF

                   application.xml

                   MANIFEST.MF

             jmsTest.jar

                   MANIFEST.MF

                   org.america3.gotest.server.messagingJmsTestMsgBean.class

       

      6. MINIMIZED EXTRACT FROM WILDFLY SERVER.LOG            

      ####WILDFLY STARTED WITH jmsTest.ear STORED IN standalone/deployments

      09:33:56,905 INFO  JBoss Modules version 1.4.3.Final

      09:33:57,125 INFO  JBoss MSC version 1.2.6.Final

      09:33:57,198 INFO  WFLYSRV0049: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) starting

       

      #### Java Client sends 1st message.  WildFly instantiates 3 MDBs

      09:34:00,285 INFO  WFLYMSG0002: Bound messaging object to jndi name java:jboss/DefaultJMSConnectionFactory

      09:34:00,319 INFO  WFLYEJB0042: Started message driven bean 'JmsTestMsgBean' with 'hornetq-ra.rar' resource adapter

       

      #### The following lines all printed from

      #### (default-threads - 1)

      09:34:00,382 INFO  WFLYSRV0010: Deployed "jmsTest.ear" (runtime-name : "jmsTest.ear")

       

      ####  MDB#1

      09:34:00,381 INFO   MDB:constructor():  beg

      09:34:00,382 INFO     MDB:constructor():  obtained InitialContext

      09:34:00,385 INFO                      :     javax.naming.InitialContext@4f2ddba9

      09:34:00,387 INFO     MDB:constructor():  Connection Factory looked up

      09:34:00,487 INFO                      : org.hornetq.ra.HornetQRAConnectionFactoryImpl@1adbb333

      09:34:00,488 INFO     MDB:constructor():  Connection established

      09:34:00,491 INFO                      : org.hornetq.ra.HornetQRASessionFactoryImpl@13945469

      09:34:00,493 INFO     MDB:constructor():  svrSendQueue looked up

      09:34:00,494 INFO                      :     HornetQQueue[goSvrSendQueue]

      09:34:00,497 INFO     MDB:constructor():  svrSendQueue cast to Destination

      09:34:00,498 INFO     MDB:constructor():  Session instantiated

      09:34:00,512 INFO                      :     org.hornetq.ra.HornetQRASession@3a8003c4

      09:34:00,513 INFO     MDB:constructor():  Producer instantiated

      09:34:00,515 INFO                      : org.hornetq.ra.HornetQRAMessageProducer@51c6b988

      09:34:00,528 INFO   MDB:constructor():  end

       

      #### MDB #2

      09:34:00,530 INFO   MDB:constructor():  beg

      09:34:00,531 INFO     MDB:constructor():  obtained InitialContext

      09:34:00,533 INFO                      :     javax.naming.InitialContext@119e4374

      09:34:00,535 INFO     MDB:constructor():  Connection Factory looked up

      09:34:00,540 INFO                      :     org.hornetq.ra.HornetQRAConnectionFactoryImpl@1adbb333

      09:34:00,542 INFO     MDB:constructor():  Connection established

      09:34:00,545 INFO                      : org.hornetq.ra.HornetQRASessionFactoryImpl@7fde1fad

      09:34:00,547 INFO     MDB:constructor():  svrSendQueue looked up

      09:34:00,551 INFO                      :     HornetQQueue[goSvrSendQueue]

      09:34:00,553 INFO     MDB:constructor():  svrSendQueue cast to Destination

      09:34:00,555 INFO     MDB:constructor():  Session instantiated

      09:34:00,557 INFO                      :     org.hornetq.ra.HornetQRASession@f699aa1

      09:34:00,559 INFO     MDB:constructor():  Producer instantiated

      09:34:00,561 INFO                      :     org.hornetq.ra.HornetQRAMessageProducer@28421822

       

      #### These were printed inbetween the above output lines from MDB

      09:34:00,541 INFO  WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management

      09:34:00,543 INFO  WFLYSRV0051: Admin console listening on http://127.0.0.1:9990

      09:34:00,546 INFO  WFLYSRV0025: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) started in 4008ms - Started 337 of 523 services (244 services are lazy, passive or on-demand)

       

      #### All the remaining lines were all printed from

      ####(Thread-1 (HornetQ-client-global-threads-1918894799))

      09:34:19,406 INFO    MDB:constructor():  end

       

      #### MDB #3

      09:34:19,407 INFO    MDB:constructor():  beg

      09:34:19,407 INFO      MDB:constructor():  obtained InitialContext

      09:34:19,408 INFO                       :     javax.naming.InitialContext@19c988ae

      09:34:19,408 INFO      MDB:constructor():  Connection Factory looked up

      09:34:19,421 INFO                       : org.hornetq.ra.HornetQRAConnectionFactoryImpl@1adbb333

      09:34:19,421 INFO      MDB:constructor():  Connection established

      09:34:19,422 INFO                       : org.hornetq.ra.HornetQRASessionFactoryImpl@18ed5101

      09:34:19,422 INFO      MDB:constructor():  svrSendQueue looked up

      09:34:19,422 INFO                       :     HornetQQueue[goSvrSendQueue]

      09:34:19,423 INFO      MDB:constructor():  svrSendQueue cast to Destination

      09:34:19,423 INFO      MDB:constructor():  Session instantiated

      09:34:19,424 INFO                       :     org.hornetq.ra.HornetQRASession@1c919c3c

      09:34:19,425 INFO      MDB:constructor():  Producer instantiated

      09:34:19,425 INFO                       : org.hornetq.ra.HornetQRAMessageProducer@db71b95

      09:34:19,426 INFO    MDB:constructor():  end

       

      09:34:19,428 INFO    MDB:myInit()     : Construction completed. ver #10

       

      #### 1st message processed successfully

      09:34:19,429 INFO    MDB:onMessage(): begin

      09:34:19,430 INFO      MDB:onMessage()  : received message = "Please Send a Reply"

      09:34:19,430 INFO      MDB:onMessage()  : selector:

      09:34:19,431 INFO                       :    "w3Mij#l4"

      09:34:19,433 INFO      MDB:onMessage()  : reply message created

      09:34:19,433 INFO      MDB:onMessage()  : added String as reply Object:

      09:34:19,433 INFO                       :     "Hi. Received your message ok."

      09:34:19,434 INFO      MDB:onMessage()  : setting selector property

      09:34:19,434 INFO                       :  Key

      09:34:19,434 INFO                       :     "MyMessages"

      09:34:19,434 INFO                       :  Value

      09:34:19,435 INFO                       :     "w3Mij#l4"

      09:34:19,435 INFO      MDB:onMessage()  : message sent

      09:34:45,911 INFO    MDB:onMessage()  :  end

       

      #### Java Client sends 2nd message - fails

      09:34:45,911 INFO    MDB:onMessage(): begin

      09:34:45,912 INFO      MDB:onMessage()  : received message = "Please Send a Reply"

      09:34:45,912 INFO      MDB:onMessage()  : selector:

      09:34:45,913 INFO                       :    "w3Mij#l4"

      09:34:45,913 INFO      MDB:onMessage()  : Exception - javax.jms.IllegalStateException

      09:34:45,913 INFO      MDB:onMessage()  :  msg       - The session is closed

      09:34:45,914 INFO      MDB:onMessage()  : close any connection

       

      09:35:20,153 WARN  HQ212037: Connection failure has been detected:

                         HQ119014: Did not receive data from /127.0.0.1:52282.

                         It is likely the client has exited or crashed without closing its connection,

                         or the network between the server and client has failed. You also might

                         have configured connection-ttl and client-failure-check-period incorrectly.

                         Please check user manual for more information. The connection will now be closed.

                         [code=CONNECTION_TIMEDOUT]

      09:35:20,155 WARN  HQ222061: Client connection failed, clearing up resources for session b169a693-8fbd-11e5-9e36-5f012a31de8a

      09:35:20,156 WARN  HQ222107: Cleared up resources for session b169a693-8fbd-11e5-9e36-5f012a31de8a

      09:35:20,156 WARN  HQ222061: Client connection failed, clearing up resources for session b16d9e34-8fbd-11e5-9e36-5f012a31de8a

      09:35:20,157 WARN  HQ222107: Cleared up resources for session b16d9e34-8fbd-11e5-9e36-5f012a31de8a

      09:35:20,158 INFO  HQ221021: failed to remove connection

       

      09:43:57,526 INFO  WFLYDR0009: Content WildFly\standalone\data\content\fc\64c...

                         is obsolete and will be removed

      09:43:57,529 INFO  WFLYDR0002: Content removed from location WildFly\standalone\data\content\fc\64c...

      09:43:57,529 INFO  WFLYDR0009: Content WildFly\standalone\data\content\19\100...

                         is obsolete and will be removed

      09:43:57,532 INFO  WFLYDR0002: Content removed from location D:\Bulletproof\bpWildFly\standalone\data\content\19\100...

       

      1. 7.  ECLIPSE CONSOLE PRINTOUT FOR SUCCESSFUL RUN.

      Is there a way to prevent the red printing from being added?

       

      Begin main()

      [main]    constructor() :  selector expression.

      [main]                      MyMessages='w3Mij#l4'

      Nov 20, 2015 2:48:29 PM org.xnio.Xnio <clinit>

      INFO: XNIO version 3.3.1.Final

      Nov 20, 2015 2:48:29 PM org.xnio.nio.NioXnio <clinit>

      INFO: XNIO NIO Implementation Version 3.3.1.Final

      Nov 20, 2015 2:48:29 PM org.jboss.remoting3.EndpointImpl <clinit>

      INFO: JBoss Remoting version 4.0.9.Final

      [main]    constructor() :  ctx ok

      Nov 20, 2015 2:48:30 PM org.jboss.ejb.client.remoting.VersionReceiver handleMessage

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

      Nov 20, 2015 2:48:30 PM org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate

      INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@29f69090, receiver=Remoting connection EJB receiver [connection=Remoting connection <63b0b052>,channel=jboss.ejb,nodename=ace]} on channel Channel ID addf070c (outbound) of Remoting connection 691a7f8f to localhost/127.0.0.1:8080

      Nov 20, 2015 2:48:30 PM org.jboss.ejb.client.EJBClient <clinit>

      INFO: JBoss EJB Client version 2.1.1.Final

      [main]    constructor() :  factory look up ok

      [main]    constructor() :  from Queue ok

      [main]    constructor() :  send to Queue ok

      [main]    constructor() :  connection ok

      [main]    constructor() :  session ok

      [main]    constructor() :  consumer ok

      [main]    constructor() :  instantiated KillSomeTime Runnable ok

      [main]    constructor() :  listener set ok

      [main]    constructor() :  producer ok

      [main]  constructor() :  end of constructor ok

      [main]  main() :       message sent

      [Thread-0 (HornetQ-client-global-threads-1453774246)] Received Message

      [Thread-0 (HornetQ-client-global-threads-1453774246)] text: "Hi. Received your message ok."

      [Thread-4]  run() : Yawn #0 any message yet?

      [Thread-4]  run() :      yes.  Ok I quit

      [main]  killSomeTime(): t.join() timed out.

      [main]  killSomeTime():  ended with message returned

      [main]  main() : ending with message returned.

       

      1. 8.  ECLIPSE CONSOLE PRINTOUT FOR FAILED RUN. (RED LINES ABOVE REMOVED)

      Begin main()

      [main]    constructor() :  selector expression.

      [main]                      MyMessages='w3Mij#l4'

      [main] constructor() :  ctx ok

      [main] constructor() :  factory look up ok

      [main]    constructor() :  from Queue ok

      [main]    constructor() :  send to Queue ok

      [main]    constructor() :  connection ok

      [main]    constructor() :  session ok

      [main]    constructor() :  consumer ok

      [main]    constructor() :  instantiated KillSomeTime Runnable ok

      [main]    constructor() :  listener set ok

      [main]    constructor() :  producer ok

      [main]  constructor() :  end of constructor ok

      [main]  main() :       message sent

      [Thread-4]  run() : Yawn #0 any message yet?

      [Thread-4]  run() :      no.   Ok back to sleep

      [Thread-4]  run() : Yawn #1 any message yet?

      [Thread-4]  run() :      no.   Ok back to sleep

      [Thread-4]  run() : Yawn #2 any message yet?

      [Thread-4]  run() :      no.   Ok back to sleep

      [Thread-4]  run() : Yawn #3 any message yet?

      [Thread-4]  run() :      no.   Ok back to sleep

      [main]  killSomeTime(): t.join() timed out.

      [main]  killSomeTime():  ended w/ no message returned

      [main]  main() :  t.join() timed out. t still running.  Interrupt it.

      [Thread-4]  run(): Interrupted: on sleep cycle 4

      [main]  main() : ending with no message returned.

        • 1. Re: Why does my MessageDrivenBean JMS Session close by itself? Can/shouldn't it remain open?
          Justin Bertram Master

          From what I can tell this doesn't really have anything to do with Wildfly over against Glassfish (or any other application server) but rather it has everything to do with JMS. It looks to me like you're causing your own problem by this bit of code at the end of onMessage():

           

              if(connection != null)

                try {

                  connection.close();

                } catch (JMSException e) {

                  e.printStackTrace();

                }

           

          Section 6.1.8 of the JMS 2.0 spec says, "Closing a Connection, QueueConnection or TopicConnection closes its constituent sessions, producers, consumers or queue browsers. The connection close is sufficient to signal the JMS provider that all resources for the connection should be released."  So when the first message is processed you close the connection which closes the constituent session and producer.  Then when you process the next message you attempt to use the closed session which naturally throws an exception.

           

          In general, there's no real need to create all the JMS objects in the constructor anyway.  This is because "java:/jboss/DefaultJMSConnectionFactory" is a pooled-connection-factory and when you call createConnection() you're not actually creating the connection, you're simply retrieving it from the pool.

          • 2. Re: Why does my MessageDrivenBean JMS Session close by itself? Can/shouldn't it remain open?
            George Berish Novice

            Hi Justin, you are correct.  With that code removed it works correctly and repeatedly.  (And now that you told me I feel a bit dumb for not seeing it myself.  But I bet I could have stared at it for days and not seen it.)

             

            In any event, I hope the complete code helps the next person new to JMS.

             

            As for the DefaultJMSConnectionFactory I next want to replace using JNDI InitialContext and lookup() to get the Factory and the Queue with injection.

            As an aside, I tired using this with no luck, but that's for a different question.

            @Resource(name = "java:/jboss/exported/DefaultJMSConnectionFactory") private ConnectionFactory factory;

            @Resource(name = "jboss/exported/jms/goSvrSendQueue") private Queue svrSendQueue;

             

            However I still think my MDB needs to instantiate a Connection, Session and MessageProducer so it can produce the rely message, and send it to the Queue.  I thought my choices were to create them one time in the MDB constructor and keep them as MDB class members, or create a new Connection, Session and MessageProducer in onMessage() every time another message was received and then close them after the reply is set.

             

            But for now this pair works.  Thanks again.

            • 3. Re: Why does my MessageDrivenBean JMS Session close by itself? Can/shouldn't it remain open?
              Justin Bertram Master

              Regarding injection, I'd recommend this article.  It should be pretty straight-forward.

               

              I thought my choices were to create them one time in the MDB constructor and keep them as MDB class members, or create a new Connection, Session and MessageProducer in onMessage() every time another message was received and then close them after the reply is set.

              Aside from injection those are your two basic choices.  However, you typically wouldn't want to create the connection from a pooled-connection-factory and hold on to it because it prevents any other component from using that connection which means additional connections would have to be created.  Every use-case is different so you may not care about that, but it's worth noting.

              • 4. Re: Why does my MessageDrivenBean JMS Session close by itself? Can/shouldn't it remain open?
                George Berish Novice

                To those who follow.

                 

                The article Justin recommend is great.  But as with so much JBoss, it's only great till the end where suddenly a new thing is introduced in a lump  -- "Mavin".  I'm sure to JBoss greybeards that's something everyone would "just know".  Grin ... in addition to "just knowing" where the heck to stick that xml code it says is required.  But new people don't just know much.  I mean I've yet to fully sort out what goes were among the host of data descriptor files (web-inf.xml, jboss.xml, ejb.xml, and several others) that keep coming up in articles and answers.

                 

                Just  for information:  I'm just trying to master the minimum I need to know to re-deploy an old application I once had working on Glassfish that requires all this stuff:  Server-side MySql data base, two servlets, JNLP delivery of Java free standing Java swing GUI (JFrame) client that on a good day also used an applet to collect info from user.  And on every day swapped a lot of messages with the server-side MDB that sorted them out to an array of session beans to deal with.  All packed with Ant to and auto-deploy ear file dropped into GF.

                 

                The real value is in the Java program core on the GUI side -- at which I'm good --but as it turns out, deployment -- at which I'm self-taught -- ate all my time.  Then Oracle dumped Glassfish leaving it with a JMS bug that will never be fixed.   Which forced me to WildFly where all the deployment descriptors change.  Grin ... and while sorting out the new descriptors, I find deployment descriptors keep getting less irrelevant, although they still monopolize most thing searching for help turns up.  In Movie-Speak ... for a beginner,  "Its complicated".

                 

                Last thing. (Grin .. not really because the never really is a one last thing it seems).  Even use of the WildFly forum is not "self-evident". E.g. I'd love to implement the injection approach, because its so elegant.  But I already found that using @Resouce with the same JNDI  that works for a lookup (to replace the JNDI lookup) in my code throws an error, which I'm not sure I will solve on my own.  So I'm  guessing the thing to do is start another question focused on that alone, instead of trying to get this one extended (which would also be nice to have it all in one place..

                 

                Regardless. Your comments and suggestions should help anyone who follows.