Java tomcat 6.0.24异常:无法加载com.mysql.jdbc.SQLError

Java tomcat 6.0.24异常:无法加载com.mysql.jdbc.SQLError,java,mysql,tomcat,jdbc,tomcat6,Java,Mysql,Tomcat,Jdbc,Tomcat6,我的tomcat 5服务器在centos上频繁运行(几次/天)会产生以下错误: 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 eventua

我的tomcat 5服务器在centos上频繁运行(几次/天)会产生以下错误:

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可能正在其他地方寻找该类吗?

错误并不是找不到该类。不允许加载,因为web应用程序已停止。我怀疑这可能是在web应用程序重新启动后发生的,因为web应用程序会在短时间内停止运行。然后,代码中的一些
finalize()
方法可能试图进行一些清理,但为时已晚。无论你的代码还是MySQL驱动程序中有没有这个,我都不能说。一次在一个目录中肯定只应该有一个jar版本。您可能需要将其升级到(现在是5.1.15),以防某些可能影响您的问题得到修复。

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

因为您使用的是Tomcat5,所以我建议您将JAR放在server/lib目录中


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

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

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

根据MysqlIO.java和WebappClassLoader.java的stacktrace和源代码,我猜:

  • 其中一个webapps未部署-基于WebappClassLoader中的代码:

    //对已停止的类加载器的日志访问

    如果(!已启动){ 试一试{ 抛出新的非法状态异常(); }捕获(非法状态){ log.info(sm.getString(“webappClassLoader.stopped”,name),e); } }

  • 在web应用关闭期间,您的JDBC连接没有正确清理(您的ServletContextListener.contextDestroyed应该这样做,或者例如Spring的bean destroy方法参数)

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

我对您的问题的解决方案是,在web应用程序关闭期间检查您的JDBC连接池是如何清理的,并确保该池也被显式关闭。

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

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

我认为对于空闲连接,您必须使用连接池机制。
或者检查此链接以获取连接池“”

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

  • 确保完成数据库连接后,使用
    close()
    调用关闭连接
  • 当您打开大量连接但未显式关闭它们时,可能会发生类似这样的错误
  • 在这些情况下,很多时候,数据库实际上关闭了空闲连接,但在应用程序端表示该连接的对象仍然没有关闭
  • 发生的情况是,这些打开的连接对象处于潜伏状态,当终结器运行(从堆栈跟踪中可以明显看出)并尝试关闭连接时,您会得到
    IllegalStateException
    ,因为此连接对象与任何数据库连接都没有关联
    不要在lib文件夹中保留相同的lib和不同的版本。尝试保留最新版本,删除其他版本,然后重试。我已按照建议升级到mysql connector的最新版本(5.1.15),并删除了所有旧版本。我使用的是tomcat 6.0.24,而不是5。对不起,我打错了。