我有一个基于Spring的应用程序(打包成WAR)在Jetty和“普通”Tomcat 7中运行良好,但在使用Spring Insight部署到tc服务器时会产生奇怪的NoClassDefFoundError。无法找到它抱怨的类肯定是WEB-INF/lib
文件夹中的JAR(我已经仔细检查过Tomcat共享库文件夹中没有竞争的JAR)。
这是堆栈跟踪,显示Spring认为它找不到类HierarchicalLoop
:
java.lang.ClassNotFoundException: com.foo.HierarchicalLoop<com.foo.Loop>
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714) ~[na:na]
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) ~[na:na]
... 32 common frames omitted
Wrapped by: java.lang.NoClassDefFoundError: com/foo/HierarchicalLoop<com/foo/Loop>
at java.lang.Class.getDeclaredConstructors0(Native Method) ~[na:1.7.0_60]
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2532) ~[na:1.7.0_60]
at java.lang.Class.getConstructor0(Class.java:2842) ~[na:1.7.0_60]
at java.lang.Class.getDeclaredConstructor(Class.java:2053) ~[na:1.7.0_60]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1094) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
... 26 common frames omitted
Wrapped by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'x12Builder' defined in class path resource [spring/x12-builder-config.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: com/foo/HierarchicalLoop<com/foo/X12Loop>
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1101) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
如果我在服务器实例中禁用了Insight,则该应用程序可以正常加载,并且可以在3台不同的计算机上重现。正如我所说,WAR也在Jetty和Tomcat(没有Insight)下正确加载。所以我很确定它已经缩小到Insight所做的事情。
根据我的经验,这些神秘的NoClassDefFoundError
或ClassNotFoundException
错误通常是由类加载器混淆引起的。例如,容器的根类加载器试图从应用程序JAR加载类。但在这种情况下,Insight对我来说是一个黑盒子,我不确定它在幕后做了什么。我怀疑Spring类可能来自除我的应用程序的类加载器之外的类加载器,这可以解释为什么Spring无法在应用程序的lib
中看到来自JAR的类。但这仅仅是受过教育的猜测,即使它是准确的,我也不知道如何解决它。
有关故障排除或洞察Insight工作原理的任何想法都表示赞赏。
答案 0 :(得分:0)
事实证明,这是由于Insight中的某种限制或错误。它抱怨的类HierarchicalLoop<Loop>
导致Insight类加载器(TomcatWeavingInsightClassLoader
)出现问题,导致它将其报告为ClassNotFoundException
。它与类型参数有关;这是导致类加载器问题的两个类:
public class Loop<ChildType extends Loop> {
//...
}
public class HierarchicalLoop<ChildType extends Loop> extends Loop<ChildType> {
//...
}
这是完全有效的Java,没有其他容器/类加载器(Tomcat,Jetty,JUnit)在加载这些类时遇到任何问题。但Insight出于某种原因确实如此。
有HierarchicalLoop
的子类,但所有子类都只指定Loop
作为ChildType
参数,因此实际上并不需要该参数。所以我能够通过从HierarchicalLoop
中删除type参数来解决这个问题:
public class HierarchicalLoop extends Loop<Loop> {
//..
}
我很确定这是Insight中的一个错误;我想报告,但无法找到任何社区支持或错误报告渠道。