tomcat 6.0.24exception:无法加载com.mysql.jdbc.SQLError

经常运行centos的tomcat 5服务器(几次/天)会产生以下错误:

Apr 7, 2011 11:02:30 PM org.apache.catalina.loader.WebappClassLoader loadClass INFO: Illegal access: this web application instance has been stopped already. Could not load com.mysql.jdbc.SQLError. 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:1370) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1329) at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291) at com.mysql.jdbc.MysqlIO.quit(MysqlIO.java:1665) at com.mysql.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:4411) at com.mysql.jdbc.ConnectionImpl.cleanup(ConnectionImpl.java:1315) at com.mysql.jdbc.ConnectionImpl.finalize(ConnectionImpl.java:2761) at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method) at java.lang.ref.Finalizer.runFinalizer(Unknown Source) at java.lang.ref.Finalizer.access$100(Unknown Source) at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source) 

tomcat的lib目录包含mysql-connector-java-5.1.8-bin.jar和mysql-connector-java-5.1.6-bin.jar,而WEB-INF / lib目录只包含mysql-connector-java-5.1。 8 bin.jar。 所有三个jar文件都包含SQLError类。

我想消除这个例外。 tomcat可以在别的地方寻找这个class吗?

错误不是找不到类。 由于Web应用程序已停止,因此无法加载。 我怀疑在重新启动Web应用程序之后可能会发生这种情况,它会在短时间内停止运行。 然后代码中的一些finalize()方法可能试图进行一些清理太晚了。 无论你的代码还是MySQL驱动程序,我都不能说。 你肯定一次只能在一个目录中有一个jar版本。 您可能希望将其升级到最新版本 (现在为5.1.15),以防修复可能影响您的内容。

在WEB-INF / lib目录中只使用一个版本的jar文件。 最好使用最新版本的mysql-connector-java 5.1.26。

较新版本的Tomcat要求您将JDBC驱动程序JAR放在Tomcat / lib目录中,而不是WEB-INF中。 并且该目录中应该只有一个版本 – 您要使用的版本 – 而不是其他版本。

由于您使用的是Tomcat 5,我建议将JAR放在server / lib目录中。

我不知道这是否是您问题的根本原因,但值得一试。

您可以检查类路径中的目录顺序。 我曾经有过两个版本的jar文件:一个在工作目录中,另一个在Java Extensions目录中。 类路径的顺序是:先检查eclipse扩展目录,然后再查看工作目录。 一旦它在extensions目录中找到了jar的一个版本,它就不会继续寻找我在工作目录中指定的那个。 订单在类路径中很重要。

您的JDBC连接池在哪里配置? 它是在Tomcat的JNDI(conf / server.xml)中还是直接在您的应用程序中? 当该消息出现时,您的某个Web应用是否已取消部署/重新部署?

从MysqlIO.java和WebappClassLoader.java的堆栈跟踪和源代码我想:

  • 取消部署其中一个webapps – 基于WebappClassLoader中的代码:

    //记录对已停止的类加载器的访问

    if(!started){try {throw new IllegalStateException(); } catch(IllegalStateException e){log.info(sm.getString(“webappClassLoader.stopped”,name),e); }}

  • 在Web应用程序关闭期间,您的JDBC连接未正确清理(您的ServletContextListener.contextDestroyed应该这样做,或者例如Spring的bean destroy-method参数)

  • MySQL驱动程序代码使用的一些类被GC卸载
  • 当应用程序关闭但GC发现MySQL连接终结方法被覆盖以便执行它时,这些连接符合GC条件
  • 当执行finalize方法时,它需要一个需要加载的类。 停止的Web应用程序的Tomcat的类加载器会检测到它,并报告停止的Web应用程序不应该加载其他类。

我的问题的解决方案是检查在Web应用程序关闭期间如何清理JDBC连接池,并确保池也明确关闭。

您最有可能在您正在检查数据库连接的应用程序中使用连接池。

我认为你必须使用连接池机制进行空闲连接。 或者检查此链接以获取连接池’ http://www.mkyong.com/hibernate/how-to-configure-the-c3p0-connection-pool-in-hibernate/

除了仅使用一个版本的jar(其他用户建议),请检查以下内容:

  1. 确保在完成数据库连接后,使用close()调用关闭连接
  2. 当您打开连接数并且未明确关闭它们时,可能会发生这样的错误。
  3. 在这些情况下,很多次,数据库实际上关闭了空闲连接,但是在应用程序端表示该连接的对象仍未关闭。
  4. 发生的事情是,这些打开的连接对象潜伏着,当终结器运行时( 从堆栈跟踪中显而易见 )并尝试关闭连接,您会得到IllegalStateException因为此连接对象与任何数据库连接都没有关联。