文
章
目
录
章
目
录
最近一个同学的项目在打包部署tomcat后报错如下:
[mysql-cj-abandoned-connection-cleanup] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1440)
at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1065)
at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.checkThreadContextClassLoader(AbandonedConnectionCleanupThread.java:117)
at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:84)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1440)
at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1065)
at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.checkThreadContextClassLoader(AbandonedConnectionCleanupThread.java:117)
at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:84)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
具体类似如图:

一开始以为这个错是因为打war包出现的问题,因为项目本身在idea开发工具中是能正常启动运行,一点错没有,只是通过maven打成war包部署到云服务器上的tomcat中,一启动到最后就报如上错误,那么这个问题该如何解决呢?
解决方案
先说下网上一种方案,潘老师也试过但好像没用,但还是说明下:
网上这种解决方案是在tomcat的servel.xml的Context标签中加个reloadable="false"属性,其实默认配置里好像没有这个标签,可能用eclispe部署或者idea部署进去才会有,我自己手工加了这个标签,没有能解决问题。
下面是重点,通过如下方法,确实解决了该问题,只需如下操作即可:
我们在项目中新建一个名为ContextFinalizer的监听类,具体代码如下:
package com.panziye.listener;
import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
@WebListener
public class ContextFinalizer implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) {}
public void contextDestroyed(ServletContextEvent sce) {
Enumeration<Driver> drivers = DriverManager.getDrivers();
Driver d = null;
while (drivers.hasMoreElements()) {
try {
d = drivers.nextElement();
DriverManager.deregisterDriver(d);
} catch (SQLException ex) {
}
}
try {
// 注意:mysql8版本的jar好像shutdown方法私有了,只能调用checkedShutdown或uncheckedShutdown
AbandonedConnectionCleanupThread.checkedShutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
提示:
@WebListener这个注解相当于在web.xml配置如下内容
<listener>
<listener-class> com.panziye.listener.ContextFinalizer </listener-class>
</listener>
然后我们再去打包部署,运行tocmat,发现就不报错了,mysql-cj-abandoned-connection-cleanup非法访问:此Web应用程序实例已停止的问题成功解决。





