我们有一个运行在Tomcat 8上的Web应用程序,最近我们发现,我们团队中的一些开发人员构建的“war文件”会抛出“NoClassDefFoundError”异常,而其他人构建的相同代码则可以正常使用。
从“logs/localhost.2018-05-11.log”中可见:
"好的"战争没有按字母顺序排序,但似乎有一些"好的"命令和一些"坏的"命令。
起初我以为我们可能有不同jar包中多个版本的DefaultEllipsoid类,导致正确版本和另一个版本之间存在竞争条件,但事实并非如此。
我在tomcat中启用了详细的类加载器调试,在两种情况下,logs/catalina.out都显示该类从正确的jar包中加载:
从“logs/localhost.2018-05-11.log”中可见:
org.jboss.resteasy.spi.UnhandledException: java.lang.NoClassDefFoundError: Could not initialize class org.geotools.referencing.datum.DefaultEllipsoid
...
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.geotools.referencing.datum.DefaultEllipsoid
at org.geotools.referencing.GeodeticCalculator.<init>(GeodeticCalculator.java:277)
...
有时候出现,但不总是,伴随着以下情况(之前出现):
org.jboss.resteasy.spi.UnhandledException: java.lang.IncompatibleClassChangeError: Implementing class
...
检查war文件时,工作和损坏的构件的内容似乎完全相同,除了一个显著的例外,在WEB-INF/lib
中jar文件的“目录排序”不同。
在爆炸的war文件上执行以下过程并重新启动Tomcat似乎可以消除异常:
$ # jars in "bad" order
$ ls -U WEB-INF/lib
x.jar
b.jar
y.jar
a.jar
c.jar
z.jar
$ cp -p WEB-INF/lib/* /tmp/lib/
$ rm -r WEB-INF/lib
$ mv /tmp/lib WEB-INF/lib
$ # jars in "good" order (appears to be alphabetical after a 'cp' on my system)
$ ls -U WEB-INF/lib
a.jar
b.jar
c.jar
x.jar
y.jar
z.jar
"好的"战争没有按字母顺序排序,但似乎有一些"好的"命令和一些"坏的"命令。
起初我以为我们可能有不同jar包中多个版本的DefaultEllipsoid类,导致正确版本和另一个版本之间存在竞争条件,但事实并非如此。
我在tomcat中启用了详细的类加载器调试,在两种情况下,logs/catalina.out都显示该类从正确的jar包中加载:
[Loaded org.geotools.referencing.datum.DefaultEllipsoid from file: /opt/tomcat/temp/1-webapp/WEB-INF/lib/gt-referencing-11.4.jar]
这里发生了什么事情有什么想法吗?
细节:
- CentOS 7
- Apache Tomcat/8.0.43
- Java 1.8.0_144
- Apache Maven 3.3.9
for j in *.jar; do echo "----> $j"; jar -tvf $j | grep 'your\.class\.name' ; done
以验证该类不在2个或更多的JAR文件中存在。 - LMC