2011-02-09 4 views
12

Ciao a tutti Ho una classe ha un init-metodo definito in XMLaccesso illegale: questa istanza applicazione web è stata interrotta già

<bean id="appStarter" class="com.myapp.myClass" init-method="init" destroy-method="destroy"/> 

myClass:

public class myClass{ 

    private Thread t; 

    public void init() { 

      t = new Thread() { 

       @Override 
       public void run() { 
        while (true) 
         try { 
          doStuff(); 
          Thread.sleep(1000); 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
       } 

      }; 
      t.start(); 
     } 

public void destroy() { 
     t.interrupt(); 
    } 

} 

quando l'applicazione inizia questo thread funziona bene, e tutto funziona bene e dopo qualche volta ho avuto la seguente eccezione

INFO: Illegal access: this web application instance has been stopped already. Could not load com.sun.mail.imap.IMAPStore. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact. 
java.lang.IllegalStateException 
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1273) 
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233) 
    at javax.mail.Session.getService(Session.java:755) 
    at javax.mail.Session.getStore(Session.java:569) 
    at javax.mail.Session.getStore(Session.java:531) 
    at javax.mail.Session.getStore(Session.java:510) 

nel metodo doStuff:

public void doStuff(){ 

Session sessioned = Session.getDefaultInstance(System.getProperties(), 
       null); 
     Store store = sessioned.getStore("imap"); 
     store.connect(hostName, userName, password); 
. 
. 
. 

} 

non so il motivo per cui, tutte le idee?

risposta

22

Problema risolto dopo il riavvio di tomcat e apache, il tomcat stava memorizzando nella cache la versione più vecchia dell'app.

+13

Come posso risolvere questo problema in modo permanente? Qual è la causa principale di questo problema? Perché sta bloccando la mia applicazione di produzione. Non voglio riavviare i server tutto il tempo ... Ho bisogno di aiuto. – vissu

+0

In secondo luogo, un riavvio di Tomcat ha risolto il problema. – Gruber

+1

Questo è probabilmente un problema di hotdeployment + thread già avviati, probabilmente non propri thread ma da librerie di terze parti. [Vedi la mia risposta qui] (http://stackoverflow.com/a/41503819/1075524). –

6

Sospetto che ciò si verifichi dopo un tentativo di annullamento della distribuzione dell'app. Hai mai effettuato l'inizializzazione durante il processo kill off that thread durante il processo init()? Lo farei nel corrispondente metodo destroy().

+0

esatto, si verifica dopo la distribuzione, e io non uccido di questo thread, come farlo, si prega di avvisare? –

+1

ok dopo qualche ricerca ho apportato alcune modifiche al codice, ma ho ancora lo stesso errore, puoi vedere le modifiche nel codice sopra? –

+0

anche quando ho usato l'interrupt nel metodo destroy, otteniamo sempre la stessa eccezione –

4

In breve: questo è probabile quando si eseguono hot-deploying webapps. Ad esempio, il tuo server di sviluppo ide + hot distribuisce di nuovo una guerra. I thread, che sono stati creati in precedenza, sono ancora in esecuzione. Ma nel frattempo il loro classloader/contesto non è valido e affronta IllegalAccessException/IllegalStateException perché la sua webapp iniziale (il precedente ambiente di runtime) è stata ridistribuita.

Quindi, come riportato qui, un riavvio non risolve in modo permanente questo problema. Invece, è meglio trovare/implementare un pool di thread gestito, s.th. come questo per gestire la terminazione dei thread in modo appropriato. In JavaEE utilizzerai questi ManagedThreadExeuctorServices. A similar opinion and reference here.

Esempi di questo sono il EvictorThread di Apache Commons Pool, che "pulisce" le istanze raggruppate in base alla configurazione del pool (max idle ecc.).