2012-08-06 6 views
5

Ho riscontrato un problema con una strategia di ricollegamento JMS. Non sono sicuro se lo sto facendo correttamente (molto probabilmente non lo sono). Ad ogni modo, sto usando WebLogic e questo è un cliente consumatore. Ecco come ottengo una connessione e provo ad aggiungere la riconnessione automatica. Il problema è che non si ricollega, e non ci sono eccezioni che registrano cosa-così-mai. Ricreare la situazione avviando weblogic, avviando client consumer che acquisisce la connessione iniziale, chiudo weblogic in modo abraso, quindi riavvio weblogic a quel punto tutti i messaggi nella coda che questo utente sta ascoltando rimangono in coda senza essere riconosciuti dal momento che non vengono ricevuti.Riconnettersi al server JMS inizialmente e dopo aver già ottenuto una connessione precedente

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()); 
     } 
    } 

risposta

3

Quindi ho finalmente capito il problema. Il problema principale con il listener di eccezioni che non veniva chiamato era dovuto alla presenza di barattoli in competizione nel mio percorso di build. Ho avuto wlfullclient.jar e wljmsclient.jar e wlsasclient.jar nel mio percorso di build Dopo aver rimosso wljmsclient.jar e wlsasclient.jar, ho iniziato a ricevere messaggi di errore che mi permettevano di eseguire il debug di più. Ecco la mia soluzione finale che cercherà di connettersi ogni 30 secondi sulla connessione iniziale, e poi cercherà di ricollegare ogni 30 secondi se si è guadagnato una connessione, ma poi ha perso:

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

Se il la connessione non può essere acquisita alla fine si otterrà un errore StackOverflow dovuto alla chiamata ricorsiva dal blocco catch –