2011-04-09 69 views
6

我的tomcat服务器5在CentOS运行频繁(多次/天)产生以下错误:的Tomcat 6.0.24异常:无法加载com.mysql.jdbc.SQLError

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可以找别的地方去找这个班吗?

+2

不要在lib文件夹中保留相同的lib不同版本。尝试保留最新的一个并删除其他人并尝试。 – Senthil 2011-04-09 20:30:00

+0

按照建议升级到建议的最新版本(5.1.15)mysql-connector并删除所有旧版本。 我使用tomcat 6.0.24而不是5.对不起,关于错字。 – user1621123 2011-04-10 19:06:04

回答

4

错误不是找不到类。它不被允许加载,因为Web应用程序已停止。我怀疑这可能是在Web应用程序重新启动之后发生的,它在很短的时间内关闭。然后在代码中的一些finalize()方法可能试图做一些清理太晚。无论是否在你的代码或MySQL驱动程序,我不能说。你绝对应该一次只能在一个目录中有一个jar版本。您可能想将其升级到latest(5.1.15现在),以防万一有可能影响到您的事情被修复。

1

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

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

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

+2

呃真的吗?链接? – MJB 2011-05-06 04:07:49

0

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

0

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

从MysqlIO.java和WebappClassLoader.java的堆栈跟踪和源代码我猜:取消部署

  • 的Web应用程序的一个 - 基于WebappClassLoader代码:

    //日志访问停止类加载器

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

  • 您的JDBC连接不web应用程序关闭期间清理正确(您ServletContextListener.contextDestroyed应该这样做或如Spring的bean的破坏,方法参数)

  • 一些被MySQL驱动程序代码中使用的类的得到了由GC
  • 卸载这些连接GC资格当你的应用程序停机,但GC发现MySQL连接完成方法重写,因此执行它
  • 当执行finalize方法时,它需要一个需要加载的类。 Tomcat的停止Web应用程序的类加载器会检测到它并报告应该没有其他类停止的Web应用程序加载。

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

0

你很可能是在你的应用程序正在检查数据库连接的usign连接池。

2

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

0

除此之外,请检查下面还有:

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