java - 由于后台线程,tomcat 无法重新加载上下文

标签 java spring tomcat background-process

我有一个使用 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)

注意:检查堆栈跟踪。有很多这样的异常(exception)。

然后对于缺少的 jdbc 驱动程序有更多的异常(exception),这绝对没问题。

有什么想法吗?

最佳答案

你确定 crawlingThread.interrupt();正在终止线程的运行。

没有看到run()的代码。看起来它可能有一个名为 crawl 的方法,它会做两件事中的一件

1) 一个期望 boolean 变量停止运行的循环,以及一些可能的 sleep /等待。我看到一个中断,但没有设置 boolean 值来终止线程循环。

2) 它运行一次(无循环)并且在完成时死亡 - 但是,我看不到中断在这里有什么帮助。

将 Thread 变量赋值为 null 无助于终止线程。

如果你想快速修复,你可以尝试将线程设置为守护线程以允许它终止。

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

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

但是如果没有代码,我猜线程会因为问题 1 或问题 2 而拒绝正常结束。

关于java - 由于后台线程,tomcat 无法重新加载上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6869671/

相关文章:

java - 在 Android 上创建视频文件

java - 使用aspectj进行springboot日志记录获取IllegalArgumentException:错误在::0在切入点中正式未绑定(bind)

tomcat - 如何在tomcat上做双向认证?

java - org/hibernate/HibernateException : Unsupported major. 次要版本 52.0(无法加载类 org.hibernate.HibernateException)

java - 使用 jersey servlet 容器访问 Web-INF 文件夹

java - preHandle 中除了 HandlerMethod 之外还有什么处理程序?

java - 如何自动将所有 Lucene TermQuery 对象转换为 PrefixQuery?

java - 上传 .pdf、.doc 或 .docx 时出现 HTTP 错误。使用 primefaces 上传工具上传文件

spring - 提供列表的@Bean-method 被忽略,如果有一个@Bean-method 证明单个bean

java - 如何使用 HashMap 模拟我的 Mongodb 存储库