2011-07-29 73 views
1

我有一個Spring的JSF2項目。它是在附有tomcat的eclipse上開發的。這是非常簡單的,主要是默認設置。因爲後臺線程,tomcat無法重新加載上下文

但是,我們有看起來像這樣的一些後臺線程:

public class CrawlingServiceImpl implements CrawlingService, InitializingBean{ 
    private final Runnable crawlingRunnable = new Runnable() { 
     @Override 
     public void run() { 
      //... 
     } 
    }; 

    public void startCrawling() { 
     crawlingThread = new Thread(crawlingRunnable); 
     crawlingThread.start(); 
    } 

    public void stopCrawling(){ 
     if (crawlingThread!=null) 
      crawlingThread.interrupt(); 
     crawlingThread = null; 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     startCrawling(); 
    } 

    public void destroy(){ 
     stopCrawling(); 
    } 
} 

這裏是誰在呼叫的destroy()方法:

<bean 
    id="crawlingService" 
    class="com.berggi.myjane.service.CrawlingServiceImpl" 
    autowire="byName" 
    scope="singleton" 
    destroy-method="destroy"/> 

我知道,有一個更好的方式,所有這是完成。但這不是我的代碼,我不想重寫它。

我的問題是這樣的: 當我改變了一個類(每一次),或者當我改變XHTML文件(很少)服務器嘗試重新加載它,但它失敗,出現以下錯誤:

INFO: Illegal access: this web application instance has been stopped already. Could not load org.apache.xml.dtm.ref.DTMManagerDefault. 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:1562) 
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521) 
    at org.apache.xml.dtm.ObjectFactory.findProviderClass(ObjectFactory.java:508) 
    ... 
    at package.CrawlingServiceImpl.crawl(CrawlingServiceImpl.java:92) 
    at package.CrawlingServiceImpl$1.run(CrawlingServiceImpl.java:39) 
    at java.lang.Thread.run(Thread.java:680) 

注意:檢查堆棧跟蹤。這些例外有很多。

然後有一個丟失的JDBC驅動程序這是絕對罰款例外。

任何想法?

+3

我硬着頭皮重寫。這是在Java EE Web應用程序中運行後臺進程的一種非常糟糕的方式。 – BalusC

+0

我必須與同事討論。順便說一句,用JSF和Spring實現後臺作業的更好方法是什麼? – mist

回答

0

你確定crawlingThread.interrupt();正在殺死線程的運行。

沒有看到run()的代碼。它看起來像它可能有一個方法叫抓取和它1 2的東西

1)一個循環需要一個布爾變量來阻止它運行,而有些可能睡覺/等待。我看到一個interupt,但沒有設置布爾值來終止線程循環。

2)運行一次(無環),完成模具的時候 - 但是,我沒有看到interupt將如何幫助這裏。

分配線程變量設置爲null會不由自主地殺死線程。

,如果你想速戰速決,你可以嘗試線程設置爲守護線程允許它被終止。

private final Runnable crawlingRunnable = new Runnable() { 
    { 
     setDaemon(true); 
    } 

    @Override 
    public void run() { 
     //... 
    } 
}; 
     //... 
} 

但是,如果沒有代碼,我猜線程被拒絕正確死於任何問題1或2

相關問題