Tomcat 5.5 和 Tomcat 6.0 中的 ClassNotFoundException 错误



我在使用tomcat 5.5和tomcat 6.0服务器时遇到了这个奇怪的问题。我有两个 Web 应用程序将安装在 tomcat 上。当tomcat启动时,这两个Web应用程序也会同时启动,但有时一个Web应用程序由于一个应用程序中的初始化失败而无法初始化,另一个应用程序在运行时出现classnotfoundexception错误。在 tomcat 7.0 中,即使其他应用程序初始化失败,应用程序也能正常运行。

经过一些调试,我开始知道有一个名为 crystal 的 jar.jar它位于两个应用程序的 web-inf/lib 文件夹中。我已经将jar移动到tomcat的common/lib文件夹中,然后它开始正常工作。我想知道为什么它在 tomcat 7.0 中运行良好,而不是在 tomcat 5.x 和 tomcat 6.x 版本中运行良好。这些版本之间的类加载架构是否有任何变化?

谢谢

EDIT1:该库位于两个应用程序 WEB-INF\lib 目录的位置,它们与外部 DLL 没有依赖关系。刚才我读到了tomcat 5.5类加载器体系结构,并了解到每个Web应用程序都有自己的类加载器。WEB-INF\lib 文件夹和类文件夹中的库将被装入到此类加载器中。存储在公共目录下的库将被放置在共享类装入器中。然后,这个库应该单独加载到Web应用程序的单独类加载器中。即使一个Web应用程序无法启动,另一个Web应用程序也应该独立工作。这就是为什么我觉得很奇怪,需要进一步调查。

终于找到了这个问题的答案

存在一种已知的 PermGen 内存泄漏,当库类由系统类引用,因此存在时间。一例如,当 Java 发现 JDBC 驱动程序或其他一些服务时并"自动注册"它。它保留对它的引用系统,但类本身属于 Web 应用程序,必须在应用程序停止时卸载 - 但不能,因此参考。 并非所有此类引用都容易清除。

在这种情况下,一个典型的症状是第一个 Web 应用程序依赖于此系统功能的功能将成功,但第二个和其他将失败(因为在系统属于第一个 Web 应用程序,无法查看来自第二个应用程序的类加载器,反之亦然)。

Tomcat 7和最新版本的Tomcat 6具有更好的保护针对某些已知的 PermGen 内存泄漏在其默认值中配置。

Tomcat 5.5根本没有这样的保护。

编辑一些参考资料

http://people.apache.org/~markt/presentations/2010-08-05-Memory-Leaks-JavaOne-60mins.pdfhttp://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf

http://eclipse.org/mat/

http://wiki.apache.org/tomcat/FAQ/Troubleshooting_and_Diagnosticshttp://wiki.apache.org/tomcat/MemoryLeakProtection

最新更新