4 Replies Latest reply on Feb 10, 2005 1:16 PM by Adrian Brock

    Reccommended JMS reconnect pattern not working for me

    mjgreene550 Newbie

      I have read through all of the relevant posts concerning how to reconnect to a topic/queue when the network is disconnected. I have applied 4 or 5 different variations of what other people are doing and the solution that I have seen adrian give numerous times. I am using JBoss 4.0.1

      However, none are working for me. Here is what I have for reconnecting to the topic:

       private class TopicConnectionListener implements ExceptionListener {
      
       public void onException(JMSException ex) {
       System.out.println("jms exception caught");
       try {
       topicConnection.setExceptionListener(null);
      
       if(topicConnection != null ) {
       topicConnection.stop();
       topicConnection.close();
       }
       subscribeToTreeTopic();
      
       } catch (JMSException e) {
       e.printStackTrace();
       }
       }
       }
      


      This ExceptionListener class is added when the topic is subscribed to. I have confirmed this. However, I still get these exceptions every 60 seconds as dictated by the HTTPServerILService.

      17:25:15,796 WARN [Connection] Connection failure:
      org.jboss.mq.SpyJMSException: Connection Failed; - nested throwable: (java.io.IOException: ping timeout.)
       at org.jboss.mq.Connection.asynchFailure(Connection.java:436)
       at org.jboss.mq.Connection$PingTask.run(Connection.java:1385)
       at EDU.oswego.cs.dl.util.concurrent.ClockDaemon$RunLoop.run(ClockDaemon.java:364)
       at java.lang.Thread.run(Thread.java:534)
      Caused by: java.io.IOException: ping timeout.
       at org.jboss.mq.Connection$PingTask.run(Connection.java:1377)
       ... 2 more
      


      And of course my topic is not reconnected. I have a feeling i'm very close to a solution, perhaps I'm missing maybe a few lines here and there or something is out of sequence. Any input?

      Thank you all.

        • 1. Re: Reccommended JMS reconnect pattern not working for me
          Adrian Brock Master

          If the connection has failed, connection.stop() will throw an exception.

          This will bypass your close() and reconnect and jump straight to the exception
          handler.

          close() does a stop() anyway so it is redundant.

          I'd also recommend you spawn a thread to do the reconnect.
          If a reconnect is not immediately possible, you can do

          boolean reconnected = false;
          while (reconnected == false)
          {
          try
          {
           reconnect();
           reconnected = true;
          }
          catch (Throwable t)
          {
           disconnect(); // handles reconnect failing part way through
           t.printStackTrace();
          }
          
          if (reconnected == false)
           Thread.sleep(10000); // wait ten seconds before trying again
          }
          


          You can run the same routine to connect at startup,
          if your application starts with no jms server available.

          • 2. Re: Reccommended JMS reconnect pattern not working for me
            Adrian Brock Master

            The one thing you need to avoid is a "fork bomb" where
            setExceptionListener() gets invoked during reconnect().

            This is usually be handled by some synchronized state that
            says don't fork another thread if you already have some thread
            in the reconnect loop.

            • 3. Re: Reccommended JMS reconnect pattern not working for me
              mjgreene550 Newbie

              Hey Adrian,

              Thanks for the logic. That actually helped me get my topic reconnected correctly. Unforuantely I still get these damn exceptions:

              22:45:17,921 WARN [Connection] Connection failure:
              org.jboss.mq.SpyJMSException: Connection Failed; - nested throwable: (java.io.IOException: ping timeout.)
               at org.jboss.mq.Connection.asynchFailure(Connection.java:436)
               at org.jboss.mq.Connection$PingTask.run(Connection.java:1385)
               at EDU.oswego.cs.dl.util.concurrent.ClockDaemon$RunLoop.run(ClockDaemon.java:364)
               at java.lang.Thread.run(Thread.java:534)
              Caused by: java.io.IOException: ping timeout.
               at org.jboss.mq.Connection$PingTask.run(Connection.java:1377)
               ... 2 more
              


              I did however want to post how I did my reconnection logic specifically in case anyone else was interested:


               private class TopicConnectionListener implements ExceptionListener {
              
               public void onException(JMSException ex) {
               connected = false;
              
               try {
               topicConnection.close();
               } catch (JMSException e) {
               e.printStackTrace();
               }
              
               if (!reconnecting) {
               new SimpleThread("JMS Reconnection Thread").start();
               }
               }
               }
              
               private class SimpleThread extends Thread {
               public SimpleThread(String str) {
               super(str);
               }
              
               public void run() {
               reconnecting = true;
               while (!connected) {
              
               //reconnect
               subscribeToTreeTopic();
              
               if (!connected) {
               try {
               Thread.sleep(10000);
               } catch (InterruptedException e) {
               e.printStackTrace();
               }
               }
               }
               reconnecting = false;
               }
               }
              


              What I do is when I initially connect my topic, I invoke this line:
              topicConnection.setExceptionListener(new TopicConnectionListener());
              


              • 4. Re: Reccommended JMS reconnect pattern not working for me
                Adrian Brock Master

                I cannot help you any further since you have hidden all the jms invocations
                inside methods you do not show.

                Also use "READ THIS FIRST" to enable logging. It will tell you in *painful* detail
                what is happening to the connection, i.e. when it is opened, when it is closed,
                when the ping occurs, when the ping task is removed, etc.