How to re-deploy a hibernate-c3p0 project on tomcat 7 without getting strange c3p0 errors

半城伤御伤魂 提交于 2020-01-01 19:08:13

问题


If the project is re-deployed through netbeans on tomcat 7 then I get errors like

java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at com.mchange.v2.resourcepool.BasicResourcePool.checkIdleResources(BasicResourcePool.java:1481)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$2000(BasicResourcePool.java:32)
    at com.mchange.v2.resourcepool.BasicResourcePool$CheckIdleResourcesTask.run(BasicResourcePool.java:1964)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)
Exception in thread "Timer-5" java.lang.NoClassDefFoundError: com/mchange/v2/resourcepool/BasicResourcePool$AsyncTestIdleResourceTask
    at com.mchange.v2.resourcepool.BasicResourcePool.checkIdleResources(BasicResourcePool.java:1481)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$2000(BasicResourcePool.java:32)
    at com.mchange.v2.resourcepool.BasicResourcePool$CheckIdleResourcesTask.run(BasicResourcePool.java:1964)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)
Caused by: java.lang.ClassNotFoundException: com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    ... 5 more

Today we got another strange error when we tried to re-deploy the project on tomcat 7

[5:07:02 PM] Nitin - Webscraper/Tester,Java/PHP developer: java.lang.NoClassDefFoundError: com/mchange/v2/lang/VersionUtils
 com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:104)
 com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65)
 com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62)
 com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531)
 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
 org.hibernate.connection.C3P0ConnectionProvider.getConnection(C3P0ConnectionProvider.java:78)
 org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
 org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
 org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
 org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1700)
 org.hibernate.loader.Loader.doQuery(Loader.java:801)
 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
 org.hibernate.loader.Loader.doList(Loader.java:2542)
 org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
 org.hibernate.loader.Loader.list(Loader.java:2271)

We have been getting such strange errors since quite some time now. When we try to debug, we find the classes already existing.

What I can think of is dangling c3p0 connection-pooling threads, which are either not destroyed properly on re-deploying, or may be having some active-connection executing or something similar.

Are there any best practices on how to re-deploy such a project which uses hibernate & c3p0 ? Is there some code that I have to write on contextDestroyed for proper closing of c3p0 threads ?


回答1:


I was also facing the same problem and I could see the below warning in my tomcat console

Jul 30, 2014 3:20:16 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads WARNING: The web application [/rmlcrm] appears to have started a thread named [C3P0PooledConnectionPoolManager[identityToken->1hge50p9311d8syo1hfjimz|19ddf1db]-HelperThread-#0] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: java.lang.Object.wait(Native Method) com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:635)

I was reading a lot to find out a solution to this and came across the post Hibernate :OutOfMemoryError: PermGen space

One of the comment in the post by Nicholas Hemley suggested to add a custom ServletContextListener and explicitly close the C3P0 connections in contextDestroyed() method of the listener which will be executed when the application is un-deployed.

We did not use the code exactly as we did not want to hard-couple with C3P0. But we realized that we are not closing hibernate sessionFactory anywhere in our application. We added the code to close the hibernate session factory in contextDestroyed() of the ServletContextListener. Now we do not have the error and neither we get a warning in the tomcat console.

You may also want to read Hibernate : closing the session factory does not close the c3p0 connection pool




回答2:


a few thoughts:

1) if you have set up your hibernate app's lifecycle to map to your web-app's lifecycle (definitely true if hibernate and c3p0 libs live in your web-app's lib directory, potentially true even if not), you absolutely do need to make sure that c3p0 pools are destroyed prior to application recycle, often meaning a contextDestroyed method. in hibernate-speak, it is the SessionFactory that wraps the Connection pool; make sure that your application's SessionFactory is close()ed when your app shuts down on hot redeploy. there should be a symmetry: either in contextInitialized or lazily upon a first request, your SessionFactory should be initialized. it should be destroyed on application shutdown.

2) the latest (still pre-release) version of c3p0 has some settings designed to reduce the likelihood of contamination between c3p0 Threads and objects derived from expired web-app ClassLoaders, especially if c3p0 is loaded by a non web-app specific ClassLoader (e.g. if c3p0 libs live in $CATALINA_HOME/lib rather than in a webapp lib directory). if you are willing to upgrade to a prerelease [latest now is c3p0-0.9.5-pre5], then try the following new config settings:

 c3p0.privilegeSpawnedThreads=true
 c3p0.contextClassLoaderSource=library

hope this helps!



来源:https://stackoverflow.com/questions/19905673/how-to-re-deploy-a-hibernate-c3p0-project-on-tomcat-7-without-getting-strange-c3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!