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

问题描述:

大家好 我有一类在XML定义非法访问:该Web应用程序实例已停止已

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

myClass的一个初始化方法:

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); 
. 
. 
. 

} 

我不知道为什么,任何想法?

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

我怀疑这是在尝试取消部署应用程序后发生的。您是否曾在init()流程中初始化过kill off that thread?我会在相应的destroy()方法中执行此操作。

+0

正确的,它发生在取消部署后,我不杀这个线程,如何做到这一点,请指教? – 2011-02-09 13:12:03

+1

确定一些搜索后,我对代码进行了一些更改,但仍然出现相同的错误,您能否看到上面代码中的更改? – 2011-02-09 13:20:56

简而言之:发生这种情况的可能是在热部署webapps时。例如,你的ide +开发服务器再次展开一场战争。之前创建的线程仍在运行。但与此同时,它们的类加载器/上下文无效并面临IllegalAccessException/IllegalStateException,因为它的原始webapp(以前的运行时环境)已被重新部署。

因此,如此处所述,重新启动不会永久解决此问题。相反,最好找到/实现一个托管线程池s.th.像这样来适当地处理线程的终止。在JavaEE中,您将使用这些ManagedThreadExector服务。 A similar opinion and reference here

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