You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot:Tomcat非法访问异常求助(Eclipse环境)

解决Tomcat抛出的IllegalStateException(Web应用已停止仍尝试加载资源)

这个问题我之前在类似环境下也碰到过,核心原因是MySQL JDBC驱动中的AbandonedConnectionCleanupThread在Web应用停止后仍在后台运行,它试图使用已经被Tomcat销毁的Web应用类加载器加载资源,从而触发了这个非法访问异常。结合你的环境(Eclipse Mars、Tomcat 8、Java 8、Spring 5、Hibernate 5),给你几个可行的解决方案:

方案1:手动触发清理线程 shutdown

在Spring应用中添加销毁钩子,强制停止MySQL的清理线程,避免它在应用停止后继续运行。

方式A:用Spring的@PreDestroy注解

在你的配置类或者Bean中添加销毁方法:

@Configuration
public class AppShutdownConfig {

    @PreDestroy
    public void cleanUpMySQLThreads() {
        try {
            // 停止MySQL的连接清理线程
            com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            // 恢复线程中断状态
            Thread.currentThread().interrupt();
            // 可以根据需要打印日志
            e.printStackTrace();
        }
    }
}

方式B:用ServletContextListener

如果你的项目还在使用web.xml配置,可以写一个监听器在应用销毁时触发线程关闭:

public class MySQLConnectionCleanupListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        try {
            com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        // 初始化逻辑(可选)
    }
}

然后在web.xml中注册这个监听器:

<listener>
    <listener-class>com.yourpackage.MySQLConnectionCleanupListener</listener-class>
</listener>

方案2:升级MySQL JDBC驱动版本

这个线程泄漏问题在较新的mysql-connector-java版本(比如8.0.20+)中已经被官方修复。如果你能升级驱动,这个异常大概率会自动消失。

注意:升级到8.x版本后,需要调整JDBC URL的参数,比如添加时区配置:

jdbc:mysql://localhost:3306/your_db?serverTimezone=UTC&useSSL=false

同时驱动类名也从com.mysql.jdbc.Driver改成了com.mysql.cj.jdbc.Driver,记得同步修改Spring或Hibernate配置中的驱动类。

方案3:Tomcat层面的临时配置

如果不想修改代码或升级驱动,可以在Tomcat的启动脚本中添加JVM参数,让清理线程自动超时终止:

  • Linux/macOS:编辑Tomcat/bin/catalina.sh,在JAVA_OPTS中添加:
    JAVA_OPTS="$JAVA_OPTS -Dmysql.abandoned.connection.cleanup.timeout=30"
    
  • Windows:编辑Tomcat/bin/catalina.bat,添加:
    set JAVA_OPTS=%JAVA_OPTS% -Dmysql.abandoned.connection.cleanup.timeout=30
    

这个参数会让清理线程在30秒无活动后自动终止,避免它在Web应用停止后继续占用资源。

额外注意点

确保Hibernate的SessionFactory在应用停止时被正确关闭,未关闭的数据库连接也会导致清理线程一直运行。可以在Spring中添加销毁方法:

@Autowired
private SessionFactory sessionFactory;

@PreDestroy
public void closeSessionFactory() {
    if (sessionFactory != null && !sessionFactory.isClosed()) {
        sessionFactory.close();
    }
}

内容的提问来源于stack exchange,提问作者Alna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:34:52