开发者

tomcat cannot reload context because of a background thread

开发者 https://www.devze.com 2023-03-23 22:22 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消