tomcat cannot reload context because of a background thread
I have a JSF2 project with Spring. It is developed on eclipse with tomcat attached to it. It is pretty straight forward and mostly with default settings.
But, we have a few background threads that look like this:
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();
}
}
Here's who's calling the destroy()
method:
<bean
id="crawlingService"
class="com.berggi.myjane.service.CrawlingServiceImpl"
autowire="byName"
scope="singleton"
destroy-method="destroy"/>
I know that there is a better way all this to be done. But this is not my code and I don't want to rewrite it.
My problem is the following: When I change a class (every single time) or when I change an xhtml file (very rarely) the server attempts to reload it, but it fails with the following errors:
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 开发者_Python百科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)
Note: Check the stacktrace. There are a lot of these exceptions.
Then there are more exceptions for a missing jdbc driver which is absolutely fine.
Any ideas?
are you sure crawlingThread.interrupt(); is killing the running of the Thread.
Without seeing the code of run(). it looks like it probably has a method called crawl and it does 1 of 2 things
1) a loop which expects a boolean variable to stop it running, and some possible sleeps/waits. I see an interupt, but no boolean being set to terminate the threads loop.
2) it runs once (no loop) and when finished dies - however, I don't see how the interupt will help here.
Assigning the Thread variable to null will not help to kill the thread.
if you want a quick fix, you could try set the thread to a daemon thread to allow it to be terminated.
private final Runnable crawlingRunnable = new Runnable() {
{
setDaemon(true);
}
@Override
public void run() {
//...
}
};
//...
}
But without the code, I'd guess the thread is refusing to die properly due to either issue 1 or 2.
精彩评论