非法访问:此 Web 应用程序实例已停止

我有一个类,它有一个用xml定义的初始化方法

<bean id="appStarter" class="com.myapp.myClass" init-method="init" destroy-method="destroy"/>

我的类:

public class myClass{

    private Thread t;

    public void init() {

             t = new Thread() {

                @Override
                public void run() {
                    while (true)
                        try {
                            doStuff();
                            Thread.sleep(1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                }

            };
            t.start();
        }

public void destroy() {
        t.interrupt();
    }

}

当应用程序启动时,这些线程运行良好,一切正常,过了一段时间,我得到以下异常。

INFO: Illegal access: this web application instance has been stopped already.  Could not load com.sun.mail.imap.IMAPStore.  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:1273)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
    at javax.mail.Session.getService(Session.java:755)
    at javax.mail.Session.getStore(Session.java:569)
    at javax.mail.Session.getStore(Session.java:531)
    at javax.mail.Session.getStore(Session.java:510)

在 doStuff 方法中:

public void doStuff(){

Session sessioned = Session.getDefaultInstance(System.getProperties(),
                null);
        Store store = sessioned.getStore("imap");
        store.connect(hostName, userName, password);
.
.
.

}

我不知道为什么,有什么想法吗?


答案 1

重新启动tomcat和apache后问题解决了,tomcat正在缓存旧版本的应用程序。


答案 2

简而言之:当您热部署Web应用程序时,可能会发生这种情况。例如,您的ide+开发服务器再次热部署了一场战争。以前创建的线程仍在运行。但与此同时,他们的类加载器/上下文是无效的,并且面临着 IllegalAccessException/IllegalStateException,因为它的组织web应用程序(以前的运行时环境)已被重新部署。

因此,正如此处所述,重新启动并不能永久解决此问题。相反,最好找到/实现托管线程池,s.th。像这样可以适当地处理线程的终止。在JavaEE中,您将使用这些ManagedThreadExeuctorServices。类似的意见和参考在这里

这方面的例子是Apache Commons Pool的EvictorThread,它根据池的配置(最大空闲等)“清理”池化实例。