我有一个使用Spring的JSF2项目。它是在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驱动程序的更多例外,这绝对没问题。
有什么想法吗?
答案 0 :(得分:0)
你确定crawlingThread.interrupt();正在杀死Thread的运行。
没有看到run()的代码。看起来它可能有一个名为crawl的方法,它可以做两件事之一
1)一个循环,它需要一个布尔变量来阻止它运行,以及一些可能的睡眠/等待。我看到了一个中断,但没有设置布尔来终止线程循环。
2)它运行一次(没有循环),当完成死亡时 - 但是,我看不到中断在这里会有什么帮助。
将Thread变量赋值为null将无助于终止该线程。
如果您想快速修复,可以尝试将线程设置为守护程序线程以允许它终止。
private final Runnable crawlingRunnable = new Runnable() {
{
setDaemon(true);
}
@Override
public void run() {
//...
}
};
//...
}
但是如果没有代码,我认为由于问题1或2,线程拒绝正常死亡。