开发者

tomcat 6.0.24 Exception: Could not load com.mysql.jdbc.SQLError

开发者 https://www.devze.com 2023-02-23 14:07 出处:网络
My tomcat 5 server running on centos frequently (several times / day) produces the following error: Apr 7, 2011 11:02:30 PM org.apache.catalina.loader.WebappClassLoader loadClass

My tomcat 5 server running on centos frequently (several times / day) produces the following error:

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 debuggin开发者_如何学JAVAg 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'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.

I'd like to eliminate this exception. Could tomcat be looking somewhere else to try to find this class?


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.


Use only one version of jar file in WEB-INF/lib directory. Better use the latest version of mysql-connector-java 5.1.26.


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.

Since you're using Tomcat 5, I'd recommend putting the JAR in your server/lib directory.

I don't know if this is the root cause of your problem, but it's worth a try.


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.


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?

From the stacktrace and source code of MysqlIO.java and WebappClassLoader.java I would guess that:

  • 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.

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.


You are most probably usign connection pooling in you application which is checking for database connectivity.


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/'


Apart from using only one version of jar (which the other users have suggested), please check the following as well:

  1. Make sure that when you are done with the database connection, close the connection with close() call.
  2. Errors like this might occur when you open number of connections and do not explicitly close them.
  3. 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.
  4. 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.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号