首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在tomcat 7上重新部署hibernate-c3p0项目而不会出现奇怪的c3p0错误

如何在tomcat 7上重新部署hibernate-c3p0项目而不会出现奇怪的c3p0错误
EN

Stack Overflow用户
提问于 2013-11-11 11:52:29
回答 2查看 6.7K关注 0票数 2

如果该项目是通过tomcat 7上的netbeans重新部署的,那么我会得到以下错误:

代码语言:javascript
复制
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

今天,当我们试图在tomcat 7上重新部署这个项目时,我们遇到了另一个奇怪的错误。

代码语言:javascript
复制
[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)

从很长一段时间以来,我们就一直犯着这样奇怪的错误。当我们尝试调试时,我们会发现已经存在的类。

我能想到的是悬空的c3p0连接池线程,它们要么在重新部署时没有被正确销毁,要么正在执行一些活动连接或类似的东西。

对于如何重新部署这样一个使用hibernate & c3p0的项目,有什么最佳实践吗?为了正确关闭contextDestroyed线程,我必须在c3p0上编写一些代码吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-30 10:02:55

我也面临着同样的问题,我可以在我的tomcat控制台中看到下面的警告

2014年7月30日下午3:20:16 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads警告: web应用程序/rmlcrm似乎启动了一个名为/rmlcrm的线程,但未能阻止它。这很可能造成内存泄漏。线程的堆栈跟踪: com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:635) (原生方法)java.lang.Object.wait

为了找出解决这个问题的方法,我读了很多书,并偶然发现了Hibernate :OutOfMemoryError: PermGen空间的帖子。

Nicholas在文章中的一条评论建议添加一个自定义ServletContextListener,并显式关闭侦听器的contextDestroyed()方法中的C3P0连接,当应用程序未部署时将执行该方法。

我们并没有像我们不想与C3P0硬耦合一样使用代码。但是我们意识到我们并没有关闭应用程序中任何地方的hibernate sessionFactory。我们在contextDestroyed()的ServletContextListener中添加了关闭hibernate会话工厂的代码。现在我们没有错误,也没有在tomcat控制台中得到警告。

您可能还想阅读Hibernate :关闭会话工厂不会关闭c3p0连接池

票数 2
EN

Stack Overflow用户

发布于 2013-11-11 14:08:30

几点想法:

1)如果您设置了hibernate应用程序的生命周期以映射到您的web应用程序的生命周期(如果hibernate和c3p0 lib驻留在web-app的lib目录中(即使不是,也可能是正确的),则绝对需要确保c3p0池在应用程序回收之前被销毁,这通常意味着一种contextDestroyed方法。在hibernate中,封装连接池的是SessionFactory;当应用程序在热重部署时关闭时,确保应用程序的SessionFactory是close()ed。应该是对称的:无论是在contextInitialized中还是在第一次请求时,都应该初始化您的SessionFactory。应该在应用程序关闭时销毁它。

2) c3p0的最新版本(仍然是预发布版)设置了一些设置,以减少c3p0线程与从过期的web应用程序ClassLoaders派生的对象之间污染的可能性,特别是如果c3p0是由非web应用程序特定的ClassLoader加载的(例如,如果c3p0库位于$CATALINA_HOME/lib中,而不是在webapp库目录中)。如果您愿意升级到预发布(最新的现在是c3p0-0.9.5-pre5),那么尝试以下新的配置设置:

代码语言:javascript
复制
 c3p0.privilegeSpawnedThreads=true
 c3p0.contextClassLoaderSource=library

希望这能帮上忙!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19905673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档