2011-02-09 60 views
12

大家好 我有一類在XML定義非法訪問:該Web應用程序實例已停止已

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

} 

當應用程序啓動此線程運行良好,並且一切都正常工作 並且在某段時間後,我得到以下異常

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) 

在doStuff方法:

public void doStuff(){ 

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

} 

我不知道爲什麼,任何想法?

回答

22

重新啓動tomcat和apache後問題解決了,tomcat緩存了舊版本的應用程序。

6

我懷疑這是在嘗試取消部署應用程序後發生的。您是否曾在init()流程中初始化過kill off that thread?我會在相應的destroy()方法中執行此操作。

+0

正確的,它發生在取消部署後,我不殺這個線程,如何做到這一點,請指教? – 2011-02-09 13:12:03

+1

確定一些搜索後,我對代碼進行了一些更改,但仍然出現相同的錯誤,您能否看到上面代碼中的更改? – 2011-02-09 13:20:56

4

簡而言之:發生這種情況的可能是在熱部署webapps時。例如,你的ide +開發服務器再次展開一場戰爭。之前創建的線程仍在運行。但與此同時,它們的類加載器/上下文無效並面臨IllegalAccessException/IllegalStateException,因爲它的原始webapp(以前的運行時環境)已被重新部署。

因此,如此處所述,重新啓動不會永久解決此問題。相反,最好找到/實現一個託管線程池s.th.像這樣來適當地處理線程的終止。在JavaEE中,您將使用這些ManagedThreadExector服務。 A similar opinion and reference here

這個例子是Apache Commons Pool的EvictorThread,它根據池的配置(最大空閒等)「清理」池實例。