如何在编译阶段让NoClassDefFoundError暴露出来

时间:2016-09-17 07:45:43

标签: java maven noclassdeffounderror

最新我在生产环境中遇到了一个错误,就是当用户访问某些优惠券列表页面时,它有以下错误

java.lang.NoClassDefFoundError: com/myapp/common/util/WrappedBeanCopier

maven依赖就像这样

myapp
    - coupon
        - common 2.0
    - common 1.0

和仅WrappedBeanCopier中的common 2.0,实际使用的myapp是common 1.0,因此导致此次事故发生。

我想知道为什么可以成功编译和部署到tomcat?有某种方式可以让它尽快曝光吗?例如编译失败。

1 个答案:

答案 0 :(得分:1)

很遗憾,在编译过程中收到有关NoClassDefFoundError错误的通知。

原因是错误本身存在以指示此错误:

(摘自Exception类的javadoc)

  

如果Java虚拟机或ClassLoader实例尝试,则抛出该异常   加载类的定义(作为普通方法调用的一部分或   作为使用新表达式创建新实例的一部分)和否   可以找到班级的定义。

     

当前正在执行的搜索类定义存在   编译了类,但无法再找到定义。

所以真的没有反对这种错误的银弹。你可以采取哪些措施来避免它再次发生:

  • 使用Maven
  • 计算出更可靠的依赖结构
  • 更全面的测试(编译和制作之间应该有测试阶段,环境等)
  • 甚至更多的测试,因为这个错误不仅发生在类定义发生变化时,如果你的类在初始化静态变量时由于异常而无法加载,你也可能会遇到NoClassDefFoundErrors的困难。

永远不会加载的类的示例:

private static Integer someThresholdValue = MyClass.calculateThreshold();

private static Integer calculateThreshold() {
   throw new Exception("some error occured");
}

注意: 当上面的错误不是经常发生时,它会变得非常讨厌,但只有当类被尝试在应用程序的启动序列中的早期加载时,我们说Spring的上下文尚未准备好......所以每次你太急于测试时你都会得到一个NoClassDefFoundError,但是如果你在访问你的webapp之前等了10秒,那就没关系了......糟糕的回忆。