0 Replies Latest reply on Jan 14, 2016 9:38 AM by naidmer

    a4j:push does not recreate listener thread for JMS messages after connection is lost

    naidmer

      Hello,

      I have encountered strange behaviour when using a4j:push component in application.

      I am using Websphere 8.5.5.7, JSF 2.0, and richfaces 4.5.11.

      There is a Jms server and a applications server. Jms server holds the message engine. When we restart jms server, then all jms related connections are being lost.

      Basicly, if I understand it correctly, push servlet is responsible for establishing connection to Jms server and listening for jms messages. But when jms server is restarted due to any reason and connection is lost, listener thread is terminated and not initialized again. Only solution is to restart client application which I want to avoid.

       

      Here is code that is responsible for this(JMSTopicsContextImpl.java from richfaces-core):

      /**
      * Created a new JMS consumer and a thread that listens for messages using the created consumer
      */
      public synchronized void start() throws NamingException, JMSException {

         connection = createConnection();
         session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
         consumer = session.createConsumer(lookupTopic(), null, false);

         pollingThread = getThreadFactory().newThread(new Runnable() {

         public void run() {

         try {

              while (true) {

             Message message = consumer.receive();

                  if (message != null) {

                       String subtopicName = message.getStringProperty(SUBTOPIC_PROPERTY);
                        TopicKey topicKey = new TopicKey(name, subtopicName);

                        org.richfaces.application.push.Topic pushTopic = getOrCreateTopic(topicKey);
                  if (pushTopic != null) {

                   try {

                       Object messageData = getMessageData(message);
                       pushTopic.publish(messageData, subtopicName);
                   } catch (Exception e) {

                        LOGGER.error(e.getMessage(), e);
                   }

             }

           } else {

              break;
           }

        }

             } catch (JMSException e) {

              LOGGER.error(e.getMessage(), e);
              }

        }

        });
         pollingThread.start();
      }

       

       

      Exception thrown is:

       

      [1/14/16 11:35:58:020 EET] 00005dcf Application   E org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSConsumerContext$1 run CWSIA0103E: An exception occurred while receiving a message: com.ibm.wsspi.sib.core.exception.SIConnectionDroppedException: CWSIC0068E: An operation was attempted on a connection that is already closed..

                                       javax.jms.JMSException: CWSIA0103E: An exception occurred while receiving a message: com.ibm.wsspi.sib.core.exception.SIConnectionDroppedException: CWSIC0068E: An operation was attempted on a connection that is already closed..

              at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.receiveInboundMessage(JmsMsgConsumerImpl.java:1247)

              at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.receive(JmsMsgConsumerImpl.java:479)

              at org.richfaces.application.push.impl.jms.JMSTopicsContextImpl$JMSConsumerContext$1.run(JMSTopicsContextImpl.java:203)

       

       

      So the cause of exception is directly at  Message message = consumer.receive();

      It wouldn't be a problem if this could be initalized again, when page with push component is reloaded. But this thread is created only once. Is there any possible workaround for this, or could it be considered for refactor so thread doesen't exit after catching exception?

       

      Regards,

      Michael