如何解决同一个jar中发生的java.lang.NoClassDefFoundError?

时间:2017-02-01 13:08:31

标签: java exception static synchronization throwable

我在A级有以下方法。所有A,B,C类和主要类别来自' A'被调用的是在同一个jar中。

public class A {    
    private static void init() {
        if (!init) {
            synchronized (B.class) {
                if (!init) {
                    map = C.creat();
                    init = true;
                }
            }
        }
    }
}

代码在Throwable区块(第4行)投掷java.lang.NoClassDefFoundErrorsynchronized。 可能是因为所有类都在同一个jar中,没有机会在运行时找不到类。

我已经完成了Existing Question中的解决方案但无法找到解决方案。请帮忙。

B类中有静态初始化块和静态变量。

如果我使用static object/class A同步代码而不是' B',则可以解决此问题。我很想知道为什么我会遇到异常以及如何使用B类修复它。

3 个答案:

答案 0 :(得分:0)

如果你真的把那个代码编译成了JAR;并且JAR包含B.class;那么这不可能发生。

唯一的选择是:您使用的JAR已损坏;或者它不包含你认为它应该包含的内容。

因此:验证您的JAR。有些事情一定是错的。例如,使用jar tf jarfile.jar列出完整内容;并检查B.class是否真的在。

答案 1 :(得分:0)

在启动Java App时,类加载器会加载类对象或元数据。

由于以下原因,上述代码最终可能会出现在java.lang.NoClassDefFoundError中。

1>上面的静态方法init是从类A中的静态块中调用的。可能会发生类B仍未在类A之前加载并且类加载器试图锁定类B的类对象(元数据)并且未能找到类的定义。

如果您在A.class上同步,它可以工作,因为类加载器具有它的类元引用

为了使用B.class类,你可能不得不懒惰地调用A类中的init方法,并允许类加载器加载类的元信息。请避免从任何静态初始化程序块调用A类中的init()方法。

答案 2 :(得分:0)

在使用B之前,B.class中有任何方法或变量引用了吗?如果没有,那么B没有,重复,没有被初始化。对class文字的引用不会触发类初始化。 “静态阻止”是一个不正确的术语。它是“静态初始化程序块”。哪个没跑。

使用final ObjectA的{​​{1}}成员进行同步,而不是B字面值。