【问题标题】:Spring application fails on startup with NoClassDefFoundError when deployed in tc Server with Insight使用 Insight 部署在 tc Server 中时,Spring 应用程序在启动时失败并出现 NoClassDefFoundError
【发布时间】:2015-05-29 18:05:46
【问题描述】:

我有一个基于 Spring 的应用程序(打包到 WAR 中),它在 Jetty 和“普通”Tomcat 7 中运行良好,但在使用 Spring Insight 部署到 tc Server 时会产生奇怪的 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 工作原理的想法都值得赞赏。

【问题讨论】:

    标签: java spring tcserver spring-insight


    【解决方案1】:

    事实证明,这是由于 Insight 中的某种限制或错误造成的。它抱怨的类 HierarchicalLoop&lt;Loop&gt; 导致 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 中删除类型参数来解决这个问题:

    public class HierarchicalLoop extends Loop<Loop> {
        //..
    }
    

    我很确定这是 Insight 中的一个错误;我想报告它,但找不到任何社区支持或错误报告渠道。

    【讨论】:

    • E-Riz,我会将其转交给 Spring Insight 团队。谢谢你的更新。
    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 2021-08-04
    • 2014-10-25
    • 2019-12-22
    • 2014-08-21
    • 2021-01-14
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多