【问题标题】:Tomcat 9 error - mysql-cj-abandoned-connection-cleanupTomcat 9 错误 - mysql-cj-abandoned-connection-cleanup
【发布时间】:2021-05-09 09:46:54
【问题描述】:

我有一个在 Tomcat 9 中运行的程序。

当我重新启动问题时,它显示上述警告:

05-Feb-2021 09:48:34.211 WARNING [Thread-5] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [AWSApps] appears to have started a thread named [mysql-cj-abandoned-connection-cleanup] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 org.apache.catalina.loader.WebappClassLoaderBase.trackLastModified(WebappClassLoaderBase.java:963)
 org.apache.catalina.loader.WebappClassLoaderBase.findResource(WebappClassLoaderBase.java:941)
 org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1057)
 com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.checkThreadContextClassLoader(AbandonedConnectionCleanupThread.java:117)
 com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:84)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 java.lang.Thread.run(Thread.java:748)

Tomcat 版本:Tomcat 9 JVM:java-8-openjdk-amd64 mysql驱动:mysql-connector-java-8.0.20

服务器.xml

 driverClassName="com.mysql.jdbc.Driver"

我已经尝试将server.xml改成

com.mysql.cj.jdbc.Driver

但在 Catalina.out 中仍有警告。

有解决问题的指南吗?

谢谢。

【问题讨论】:

  • 您的应用程序是否也带有mysql-connector-java.jar?这是来自*LeakPreventionListeners 的唯一警告吗?可以修改程序吗?
  • 是的。我正在使用 mysql-connector-java.jar。在我的 server.xml 中,我还设置了

标签: java tomcat mysql-connector


【解决方案1】:

如果您的 Web 应用程序在 WEB-INF/lib 文件夹中有 MySQL JDBC 驱动程序的副本,则 Tomcat 中使用的特殊 delegation rules for classloaders 将选择 Web 应用程序的驱动程序副本而不是全局驱动程序副本。

这将在引导类加载器中的应用程序类加载器上创建两个引用:

  • 驱动程序将注册到DriverManager(在引导类加载器中),
  • 驱动程序将创建一个新线程,并将 ContextClassLoader 设置为 webapp 类加载器。

两个引用都可能造成内存泄漏。

备注:即使您不直接使用DriverManager,但某些数据库池库(最终将使用DriverManager)或者如果您定义了JNDI @,也会发生这种情况987654327@ 在您的<Context> 中。只有<GlobalNamingResources> 中定义的<Resource> 的大小写不受影响。

要解决问题,您可以:

  • 要么从WEB-INF/lib 目录中删除数据库驱动程序,
  • 当应用程序停止时通过调用 DriverManager.deregister 来撤销这些更改,例如在 ServletContextListener 中:
public class JdbcDriverListener implements ServletContextListener {

   /**
    * Deregisters the JDBC drivers distributed with the application.
    */
   @Override
   public void contextDestroyed(ServletContextEvent event) {
      final ClassLoader cl = event.getServletContext().getClassLoader();
      final Enumeration<Driver> drivers = DriverManager.getDrivers();
      while (drivers.hasMoreElements()) {
         final Driver driver = drivers.nextElement();
         // We deregister only the classes loaded by this application's classloader
         if (driver.getClass().getClassLoader() == cl) {
            try {
               DriverManager.deregisterDriver(driver);
            } catch (SQLException e) {
               event.getServletContext().log("JDBC Driver deregistration failure.", e);
            }
         }
      }
   }

   /**
    * Registers the JDBC drivers distributed with the application.
    */
   @Override
   public void contextInitialized(ServletContextEvent event) {
      Iterator<@NonNull Driver> driversIterator = ServiceLoader.load(Driver.class).iterator();
      while (driversIterator.hasNext()) {
         try {
            // Instantiates the driver
            driversIterator.next();
         } catch (Throwable t) {
            event.getServletContext().log("JDBC Driver registration failure.", t);
         }
      }
   }
}

编辑:我将来自 cmets 的信息合并到答案中。

【讨论】:

  • 我正在使用数据库池。在 Java 程序中,我使用 initContext 和 enviromentContext。它将引用 JDBC 池。而在 server.xml 中,我们定义了 Resource type="javax.sql.DataSource"
  • 数据库池最终调用DriverManager。如果您在应用程序的&lt;Context&gt; 中配置了&lt;Resource&gt;,它的工作方式与您在应用程序中使用DriverManager 的方式相同。从应用程序的WEB-INF/lib 文件夹中删除mysql-connector-java.jar,问题应该会停止。
  • 嗨,谢谢。从 WEB-INT/lib 中删除 mysql.jar 后,没有发生错误。但是我还对使用 com.mysql.cj.jdbc.Driver 的 server.xml 进行了更改,我还需要更改资源类型 url="jdbc:mysql://127.0.0.1:3306/aa?useLegacyDatetimeCode=false& serverTimezone=Europe/Amsterdam&useSSL=false"
猜你喜欢
  • 2014-10-31
  • 2017-07-08
  • 2018-11-25
  • 2021-07-05
  • 2021-12-13
  • 2021-10-01
  • 2023-03-06
  • 2023-01-21
  • 2016-12-09
相关资源
最近更新 更多