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

如何解决同一jar中发生的java.lang.NoClassDefFoundError?,java,exception,static,synchronization,throwable,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;

我在类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;
                }
            }
        }
    }
}
代码正在
synchronized
块(第4行)处抛出
Throwable
java.lang.NoClassDefFoundError
。 原因可能是什么?因为所有类都在同一个jar中,所以在运行时不可能找不到类

我已在中查看了解决方案,但找不到解决方案。请帮忙

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


如果我使用
静态对象/类a
来同步代码段,而不是使用“B”,那么这个问题可以得到解决。我很想知道为什么我会遇到这个异常,以及如何只使用类B来修复它。

如果你真的编译了这个代码到一个JAR中;这个JAR包含B.class;那么这就不会发生了

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


因此:验证您的JAR。一定是出了什么问题。例如,使用
jartf jarfile.jar
列出完整的内容;并检查B.class是否真的存在。

类对象或元数据是在启动Java应用程序时由类加载器加载的

由于以下原因,上述代码可能会在java.lang.NoClassDefFoundError中结束

1> 上面的静态方法init是从类a中的静态块中调用的。可能会发生这样的情况:在类a之前,类B仍然没有加载,并且类加载器试图锁定类B的类对象(元数据),并且找不到类的定义

如果您在一个.class上同步,它就会工作,因为类加载器有它的类元引用


为了使用类B.class,您可能必须在类A中惰性地调用init方法,并允许类加载器加载类的元信息。请避免从任何静态初始值设定项块调用类A中的init()方法。

在使用
B.class
之前,是否有任何内容引用了
B
中的任何方法或变量?如果没有,则
B
尚未、重复、未初始化。引用
文本不会触发类初始化。“静态块”是一个不正确的术语。这是“静态初始化程序块”。没有跑


使用
a
B
final Object
成员来同步,而不是
class
文本。

为什么要使用B.class来同步?我认为这不是一个最佳实践。B中的静态块是否可以调用
a.init
方法?能否显示jar的包结构?能否显示jd guidecompile@duffymo:是的,我知道。我已将其更改为静态对象。我只是想知道我为什么要面对error@XavierDSouza如果
B
尚未加载,则对
B.class
的引用将按照JLS的规定加载class
B
。它不会按照JLS还指定的方式初始化
B
,因此初始化程序块在此后某个时间发生初始化事件之前不会运行。这不完全正确。引用
B.class
将触发加载
B
。它在JLS中。事实上,引用
B.class
不会触发类初始化。