使用Insight在tc Server中部署时,Spring应用程序在启动时因NoClassDefFoundError而失败

时间:2015-05-29 18:05:46

标签: java spring tcserver spring-insight

我有一个基于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所做的事情。

根据我的经验,这些神秘的NoClassDefFoundErrorClassNotFoundException错误通常是由类加载器混淆引起的。例如,容器的根类加载器试图从应用程序JAR加载类。但在这种情况下,Insight对我来说是一个黑盒子,我不确定它在幕后做了什么。我怀疑Spring类可能来自除我的应用程序的类加载器之外的类加载器,这可以解释为什么Spring无法在应用程序的lib中看到来自JAR的类。但这仅仅是受过教育的猜测,即使它是准确的,我也不知道如何解决它。

有关故障排除或洞察Insight工作原理的任何想法都表示赞赏。

1 个答案:

答案 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中的一个错误;我想报告,但无法找到任何社区支持或错误报告渠道。