java tomcat 6.0.24 异常:无法加载 com.mysql.jdbc.SQLError
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5607672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
tomcat 6.0.24 Exception: Could not load com.mysql.jdbc.SQLError
提问by user1621123
My tomcat 5 server running on centos frequently (several times / day) produces the following error:
我的 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.access0(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)
tomcat's lib directory contains mysql-connector-java-5.1.8-bin.jar and mysql-connector-java-5.1.6-bin.jar, while the WEB-INF/lib directory only contains mysql-connector-java-5.1.8-bin.jar. All three jar files contain the SQLError class.
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 类。
I'd like to eliminate this exception. Could tomcat be looking somewhere else to try to find this class?
我想消除这个例外。tomcat 可以在其他地方寻找这个类吗?
回答by WhiteFang34
The error is not that the class can't be found. It's not being allowed to load because the web application has been stopped. I suspect this might be happening after the web application is restarted, where it's down for a short period of time. Then some finalize()
method in the code is probably trying to do some cleanup too late. Whether or not that's in your code or the MySQL driver I can't say. You definitely should only have one version of a jar in a directory at a time. You might want to upgrade it to the latest(5.1.15 right now) in case something has been fixed that might be affecting you.
错误不是找不到类。不允许加载,因为 Web 应用程序已停止。我怀疑这可能是在 Web 应用程序重新启动后发生的,它会在短时间内关闭。那么finalize()
代码中的某些方法可能试图做一些清理太晚了。我不能说这是否在您的代码或 MySQL 驱动程序中。您绝对应该一次在一个目录中只有一个版本的 jar。您可能希望将其升级到最新版本(现在是 5.1.15),以防某些可能影响您的问题得到修复。
回答by WhiteFang34
Use only one version of jar file in WEB-INF/lib directory. Better use the latest version of mysql-connector-java 5.1.26.
仅使用 WEB-INF/lib 目录中的一个版本的 jar 文件。最好使用最新版本的 mysql-connector-java 5.1.26。
回答by duffymo
Newer versions of Tomcat require that you put JDBC driver JARs in the Tomcat /lib directory, not your WEB-INF. And there should only be one version in that directory - the version you want to use - and no others.
较新版本的 Tomcat 要求您将 JDBC 驱动程序 JAR 放在 Tomcat /lib 目录中,而不是您的 WEB-INF。并且该目录中应该只有一个版本——您要使用的版本——而没有其他版本。
Since you're using Tomcat 5, I'd recommend putting the JAR in your server/lib directory.
由于您使用的是 Tomcat 5,我建议将 JAR 放在您的 server/lib 目录中。
I don't know if this is the root cause of your problem, but it's worth a try.
我不知道这是否是您问题的根本原因,但值得一试。
回答by ejsuncy
You could check the order of directories in the classpath. I once had two versions of a jar file: one in the working directory and another in the Java Extensions directory. The order of the classpath was: check eclipse extensions directory first, then working directory second. Once it found a version of the jar in the extensions directory, it didn't keep looking for the one I was specifying in the working directory. Order matters in the classpath.
您可以检查类路径中目录的顺序。我曾经有过两个版本的 jar 文件:一个在工作目录中,另一个在 Java Extensions 目录中。类路径的顺序是:首先检查 eclipse 扩展目录,然后是工作目录。一旦它在扩展目录中找到了一个 jar 版本,它就不会继续寻找我在工作目录中指定的那个版本。类路径中的顺序很重要。
回答by Piotrek Bzdyl
Where is your JDBC connection pool configured? Is it in Tomcat's JNDI (conf/server.xml) or directly in your application? Is one of your web apps undeployed/redeployed when that message appears?
你的JDBC连接池是在哪里配置的?它是在 Tomcat 的 JNDI (conf/server.xml) 中还是直接在您的应用程序中?出现该消息时,您的某个 Web 应用程序是否已取消部署/重新部署?
From the stacktrace and source code of MysqlIO.java and WebappClassLoader.java I would guess that:
从 MysqlIO.java 和 WebappClassLoader.java 的堆栈跟踪和源代码中,我猜想:
one of the webapps is undeployed - based on the code in WebappClassLoader:
// Log access to stopped classloader
if (!started) { try { throw new IllegalStateException(); } catch (IllegalStateException e) { log.info(sm.getString("webappClassLoader.stopped", name), e); } }
your JDBC connections are not clean up correctly during the web app shutdown (your ServletContextListener.contextDestroyed should do that or e.g. Spring's bean destroy-method parameter)
- some of the classes that are used by MySQL driver code got unloaded by GC
- those connections are GC eligible when your application shutdowns but GC finds that MySQL connection finalize method is overriden so it executes it
- when that finalize method is executed it requires a class that needs to be loaded. The Tomcat's class loader of your stopped web app detects it and reports that there should be no other classes loaded by a stopped web app.
其中一个 webapps 未部署 - 基于 WebappClassLoader 中的代码:
// 记录对停止的类加载器的访问
if (!started) { try { throw new IllegalStateException(); } catch (IllegalStateException e) { log.info(sm.getString("webappClassLoader.stopped", name), e); } }
您的 JDBC 连接在 Web 应用程序关闭期间未正确清理(您的 ServletContextListener.contextDestroyed 应该这样做,或者例如 Spring 的 bean destroy-method 参数)
- MySQL 驱动程序代码使用的一些类被 GC 卸载
- 当您的应用程序关闭时,这些连接符合 GC 条件,但 GC 发现 MySQL 连接终结方法已被覆盖,因此它会执行它
- 当执行该 finalize 方法时,它需要一个需要加载的类。您停止的 Web 应用程序的 Tomcat 类加载器检测到它并报告停止的 Web 应用程序不应加载其他类。
My solution to your problem would be to check how your JDBC connection pool is cleaned up during web app shutdown and make sure the pool is also explicitly shutdown.
我对您的问题的解决方案是检查您的 JDBC 连接池在 Web 应用程序关闭期间是如何清理的,并确保该池也已明确关闭。
回答by Java_User
You are most probably usign connection pooling in you application which is checking for database connectivity.
您很可能在检查数据库连接的应用程序中使用连接池。
回答by Suresh U
I think you have to use connection pooling mechanism for idle connections. or else check this link for connection pooling 'http://www.mkyong.com/hibernate/how-to-configure-the-c3p0-connection-pool-in-hibernate/'
我认为您必须对空闲连接使用连接池机制。或者检查此链接以获取连接池' http://www.mkyong.com/hibernate/how-to-configure-the-c3p0-connection-pool-in-hibernate/'
回答by Santosh
Apart from using only one version of jar (which the other users have suggested), please check the following as well:
除了仅使用一个版本的 jar(其他用户建议)之外,还请检查以下内容:
- Make sure that when you are done with the database connection, close the connectionwith
close()
call. - Errors like this might occur when you open number of connections and do not explicitly close them.
- In these situations, many a times, the database actually closes the idle connections but the object representing that connection on application side is still not closed.
- What happens is, these open connection objects are lurking and when the the finalizer runs (evident from the stack trace) and tries to close the connection, you get
IllegalStateException
as this connection object is not associated with any database connections.
- 确保在完成数据库连接后,通过调用关闭连接
close()
。 - 当您打开多个连接但未明确关闭它们时,可能会发生此类错误。
- 在这些情况下,很多时候,数据库实际上关闭了空闲连接,但在应用程序端表示该连接的对象仍未关闭。
- 发生的情况是,这些打开的连接对象潜伏着,当终结器运行(从堆栈跟踪中可以明显看出)并尝试关闭连接时,您会得到,
IllegalStateException
因为此连接对象与任何数据库连接都没有关联。