我们有一个Web应用程序,其实例在同一个tomcat(v6.0.14)实例下多次部署。假设war文件名为“app.war”,然后我们部署“app1.war”,“app2.war”等等。
正确部署所有应用程序实例(~20)。当访问这些应用程序上的servlet时,有时它们在tomcat的NoClassDefFoundError
中由ClassNotFoundException
导致WebAppClassLoader
失败。以下是一个例子 -
java.lang.NoClassDefFoundError: com/xxx/APISocketServer$ClientRequestHandler
at com.xxx.APISocketServer$APISocketServerThread.run(APISocketServer.java:143)
Caused by: java.lang.ClassNotFoundException: com.xxx.APISocketServer$ClientRequestHandler
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1358)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
... 1 more
违规类是应用程序代码的一部分,不属于任何库。
由于某些应用程序实例正确运行,因此不能出现类路径错误配置的情况。需要注意的一点是,只有几个类无法加载。这些类没有任何静态初始化程序块,这可能导致类初始化失败。我检查了tomcat日志(catalina.out,localhost.log),但没有发现任何类初始化错误。
我应该如何继续调试此问题?
答案 0 :(得分:2)
在进一步调查中,发现打开文件描述符(1024)的限制是罪魁祸首。每个应用程序实例都需要由其类加载器(WebappClassLoader
)打开的Jar文件的自己副本。如果在90秒内未访问Jar文件中的类,则类加载器将关闭文件。如果在短时间内访问多个应用程序实例,则openJARs
函数将失败,从而导致类未加载。
如果WebappClassLoader
在更高的日志级别打开JAR文件时记录失败,则会更早发现错误。在调试级别记录错误。启用WebappClassLoader
的调试级别有助于解决问题。