当前位置: 首页 > 知识库问答 >
问题:

Tomcat 9错误-mysql cj放弃连接清理

钱志强
2023-03-14

我有一个在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连接器-java-8.0.20

服务器xml

 driverClassName="com.mysql.jdbc.Driver"

我已经试着把server.xml变成

com.mysql.cj.jdbc.Driver

但是Catalina.out.仍然有警告

有解决这个问题的指南吗?

非常感谢。

共有1个答案

劳彦
2023-03-14

如果Web应用程序在WEB-INF/lib文件夹中有MySQL JDBC驱动程序的副本,Tomcat中使用的类加载器的特殊委托规则将选择Web应用程序的驱动程序副本,而不是全局副本。

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

  • 驱动程序将注册到DriverManager(在引导类加载器中),

这两个引用都会造成内存泄漏

备注:即使您不直接使用DriverManager,而是使用一些数据库池库(最终将使用DriverManager),或者如果您定义了JNDI

要解决这个问题,您可以:

  • WEB-INF/lib目录中删除数据库驱动程序,
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);
         }
      }
   }
}

编辑:我将评论中的信息合并到答案中。

 类似资料:
  • 自从我在linux上移动我的流服务器后,我有以下问题:我使用MPD和icecast一起,每次MPD停止播放,流就会关闭。这是一个问题,因为当我从播放列表转换为流时,MPD会删除与icecast的连接,客户端必须刷新。

  • Android和OpenCV的新版本。正在尝试实现新书中的代码,用实际的计算机视觉项目掌握OpenCV。这个应用程序基本上是用OpenCV在相机预览中渲染卡通化的图像。你可以触摸屏幕来保存卡通化的图像。 来自作者的源代码位于此处。 我对CartoonifierApp.java文件做了一个小修改(见下文),这样我就可以用OpenCV Manager应用程序静态加载cartoonifier库(原始代码

  • 我从W3Schools复制了它,当我尝试运行它时,它会给我一个错误。我是MySQL的新手,所以我正在尝试解决这个问题,但我不知道如何解决。 错误: 警告:mysqli::mysqli():(HY000/1045):用户'用户名'@'localhost'(使用密码:是)在第10行的C:\xampp\htdocs\Informatic a\test.php访问被拒绝连接失败:用户'用户名'访问被拒绝'

  • 我尝试使用HikariCP和mariaDB数据库,但是当我尝试初始化的时候,我得到了下一个错误。 由以下原因引起:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 我的MariaDBDatabase类: 我的数据库类: 我的家伙.xml

  • 我使用以下模块中的反向代理https://github.com/nodejitsu/node-http-proxy 我只需要代理调用到新的端口

  • 拒绝/丢弃到反应堆TCPServer的传入连接的正确方法是什么? 我目前有以下资料: 它似乎起作用了,并且成功地从我的列表中的远程地址丢弃连接。但每次它都将堆栈跟踪打印到控制台,而且通常情况下看起来不太好。 拒绝与tcpserver的某些连接的正确方法是什么?