2012-08-06 17 views
5

Występuje problem ze strategią ponownego łączenia się z JMS. Nie jestem pewien, czy robię to poprawnie (najprawdopodobniej nie jestem). W każdym razie korzystam z WebLogic, a to jest klient konsumencki. Oto, w jaki sposób uzyskuję połączenie i próbuję dodać automatyczne ponowne łączenie. Problem polega na tym, że nie łączy się ponownie i nie ma żadnych wyjątków, które rejestrowałyby to, co jeszcze. Ponownie tworzę sytuację, uruchamiając weblogic, uruchamiając klienta klienta, który zyskuje początkowe połączenie, kończę blogowanie, potem ponownie uruchamiam weblogic, w którym to momencie wszystkie wiadomości w kolejce, które ten konsument słucha, pozostają w kolejce bez potwierdzenia ponieważ nie są odbierane.Ponowne łączenie z serwerem JMS początkowo i po uzyskaniu poprzedniego połączenia

public void setReceiver(MessageListener listener) { 
     try { 
      Properties parm = new Properties(); 
      parm.setProperty("java.naming.factory.initial", 
        "weblogic.jndi.WLInitialContextFactory"); 
      parm.setProperty("java.naming.provider.url", URL); 
      parm.setProperty("java.naming.security.principal", username); 
      parm.setProperty("java.naming.security.credentials", password); 
      ctx = new InitialContext(parm); 
      final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx 
        .lookup(conFactoryName); 
      connection = connectionFactory.createQueueConnection(); 
      // TODO: 8/6/2012 Work on reconnection strategies for Consumer. 
      ((WLConnection) connection) 
        .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL); 
      ((WLConnection) connection).setReconnectBlockingMillis(30000L); 
      ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L); 
      session = connection.createQueueSession(false, 
        Session.AUTO_ACKNOWLEDGE); 

      queue = (Queue) ctx.lookup(queueName); 
      // receiver = session.createReceiver(queue); 
      // receiver.setMessageListener(listener); 
      consumer = session.createConsumer(queue); 
      consumer.setMessageListener(listener); 

      connection.setExceptionListener(new ExceptionListener() { 

       @Override 
       public void onException(JMSException arg0) { 
        // Assume Disconnected. 
        FileHandler fh = null; 
        try { 
         fh = new FileHandler("./logs/ExceptionListener", true); 
        } catch (SecurityException e) { 
         e.printStackTrace(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        SimpleFormatter formatter = new SimpleFormatter(); 
        fh.setFormatter(formatter); 
        Logger log2 = Logger.getLogger("ExceptionListener"); 
        log2.addHandler(fh); 
        boolean connected = false; 
        do { 
         if (connection != null) { 
          try { 
           connection.close(); 
          } catch (JMSException e) { 
           log.warning(e.toString()); 
          } 
          try { 
           connection = connectionFactory.createQueueConnection(); 
           connection.setExceptionListener(this); 
           connection.start(); 
           connected = true; 
          } catch (JMSException e) { 
           log.severe(e.toString()); 
          } 
         } 
        } while (!connected); 

       } 
      }); 
      connection.start(); 

     } catch (JMSException je) { 
      log.severe(je.getMessage()); 
     } catch (Exception e) { 
      log.severe(e.getMessage()); 
     } 
    } 

Odpowiedz

3

W końcu udało mi się rozwiązać problem. Głównym problemem, z którym nie został wywołany detektor wyjątków, było posiadanie konkurujących słoików na ścieżce budowania. Miałem wlfullclient.jar i wljmsclient.jar i wlsasclient.jar w mojej ścieżce budowania Po usunięciu wljmsclient.jar i wlsasclient.jar, zacząłem otrzymywać komunikaty o błędach, które pozwoliły mi dalej debugować. Oto moje ostateczne rozwiązanie, które będzie próbowało łączyć się co 30 sekund podczas pierwszego połączenia, a następnie spróbuje połączyć się co 30 sekund, jeśli uzyska połączenie, ale następnie je utraciło:

public boolean setReceiver(MessageListener listener) { 
     try { 
      Properties parm = new Properties(); 
      parm.setProperty("java.naming.factory.initial", 
        "weblogic.jndi.WLInitialContextFactory"); 
      parm.setProperty("java.naming.provider.url", URL); 
      parm.setProperty("java.naming.security.principal", username); 
      parm.setProperty("java.naming.security.credentials", password); 
      ctx = new InitialContext(parm); 
      final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx 
        .lookup(conFactoryName); 
      connection = connectionFactory.createQueueConnection(); 
      ((WLConnection) connection) 
        .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL); 
      ((WLConnection) connection).setReconnectBlockingMillis(30000L); 
      ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L); 
      session = connection.createQueueSession(false, 
        Session.AUTO_ACKNOWLEDGE); 
      queue = (Queue) ctx.lookup(queueName); 
      consumer = session.createConsumer(queue); 
      consumer.setMessageListener(listener); 

      connection.setExceptionListener(new ExceptionListener() { 
       @Override 
       public void onException(JMSException arg0) { 
        // Assume Disconnected. 
        Logger log2 = new MyLogger().getLogger("BPEL Client"); 
        if (arg0 instanceof LostServerException) { 
         log2.severe("Connection to the Server has been lost, will retry in 30 seconds. " 
           + arg0.toString()); 
        } else { 
         log2.severe(arg0.toString()); 
        } 

       } 
      }); 
      connection.start(); 
      log.info("Successfully connected to " + URL); 
      return true; 
     } catch (JMSException je) { 
      log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. " 
        + je.getMessage()); 
      try { 
       Thread.sleep(30000L); 
      } catch (InterruptedException e) { 
       log.warning(e.toString()); 
      } 
      return setReceiver(listener); 
     } catch (Exception e) { 
      log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. " 
        + e.toString()); 
      try { 
       Thread.sleep(30000L); 
      } catch (InterruptedException ie) { 
       log.warning(ie.toString()); 
      } 
      return setReceiver(listener); 

     } 
    } 
+3

Jeśli nie można uzyskać połączenia, w końcu dostaniesz błąd stackoverflow z powodu rekursywnego wywołania z bloku catch –