[英]java.lang.NoClassDefFoundError: Could not initialize class | static block
我遇到了一个奇怪的问题,我的 JVM 抛出了 java.lang.NoClassDefFoundError。 非常感谢您在识别问题方面的任何帮助。
public class AccessorFactory
{
private static Map classMap = null;
static
{
classMap = new HashMap(100);
classMap.put("bills", Class.forName("com.example.BillAccessor"));
}
}
public class BillAccessor
{
class BillInnerClass
{
//some code
}
}
我有 3 个类 AccessorFactory.class、BillAccessor.class 和 BillAccessor$BillInnerClass.class。 所有 3 个都在同一个 jar 文件中,并且都存在于类路径中。
我最近更改了 BillAccessor$BillInnerClass 类中的一些内容,并在 jar 文件中替换了这个文件,并在服务器(jboss)中重新启动了应用程序实例。
重启后我得到
java.lang.NoClassDefFoundError: Could not initialize class AccessorFactory
AccessorFactory 类存在于 jar 文件和类路径中。 除了我替换了 BillAccessor$BillInnerClass 之外,没有其他任何变化。
NoClassDefFoundError
通常意味着 JVM 已找到该类(与ClassNotFoundException
相反),但由于没有一些依赖类而无法加载它。
不确定您是否尝试重建整个 jar(包含所有 3 个类)并在 JBoss 中使用新 jar?
这是一个老问题,但我认为它值得一个更好的答案。
这里实际上发生了两件事。
在问题讨论的异常之前的一段时间,JVM 已尝试为AccessorFactory
类执行静态初始化。 这引发了未经检查的异常,导致初始化失败。 因此, AccessorFactory
类被标记为失败。 它实际上已经死了。 JVM 永远不会重试初始化。
您看到的异常是NoClassDefFoundError
。 发生这种情况是因为1 JVM 试图加载或初始化另一个依赖于AccessorFactory
的类。 JVM 注意到AccessorFactory
已被标记为失败,并抛出此异常。
那么是什么导致了原来的问题呢?
不幸的是,我们不能说。 资料不足2 . 静态初始化器中的代码是:
classMap = new HashMap(100);
classMap.put("bills", Class.forName("com.example.BillAccessor"));
第一条语句失败的可能性很小,但第二条语句正在尝试加载一个类。 这可能由于多种原因而失败,包括以下原因。
它可能根本找不到类。 这将导致ClassNotFoundException
。
它可以检测到正在加载的.class
文件中的错误,这会导致某种Error
。
它可以检测到正在加载的.class
文件与已加载的其他一些类之间的二进制版本不兼容。 这是一系列可能导致这种情况的事情,但它们也会导致某种Error
。
1 - 异常也可能由于其他原因而发生,但在这种情况下,异常的消息告诉我们这是较早的类初始化失败。
2 - 真正的原因很可能在较早的堆栈跟踪中报告,该堆栈跟踪可能在 OP 的日志文件中较早。
话虽如此,我认为问题中的代码不是“真实的”。 具体来说,如图所示的static
不应该编译。 forName
抛出的ClassNotFoundException
是一个检查异常,它必须被捕获。 JLS 不允许检查异常从static
块传播。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.