tomcat中的ClassNotFoundException是servlet代码中的内部类

时间:2013-03-04 05:50:20

标签: tomcat classnotfoundexception

我们有一个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),但没有发现任何类初始化错误。

我应该如何继续调试此问题?

1 个答案:

答案 0 :(得分:2)

在进一步调查中,发现打开文件描述符(1024)的限制是罪魁祸首。每个应用程序实例都需要由其类加载器(WebappClassLoader)打开的Jar文件的自己副本。如果在90秒内未访问Jar文件中的类,则类加载器将关闭文件。如果在短时间内访问多个应用程序实例,则openJARs函数将失败,从而导致类未加载。

如果WebappClassLoader在更高的日志级别打开JAR文件时记录失败,则会更早发现错误。在调试级别记录错误。启用WebappClassLoader的调试级别有助于解决问题。