java.lang.NoClassDefFoundError:无法初始化类XXX

时间:2011-09-06 20:12:10

标签: java jar runtime noclassdeffounderror

public class PropHolder {
  public static Properties prop;

  static {
    //code for loading properties from file
  }
}

// Referencing the class somewhere else:
Properties prop = PropHolder.prop;

class PropHolder是我自己的一类。该类驻留在主类的同一JAR文件中。所以这不应该因为类路径中缺少任何JAR。

当我通过jar tf myjarfile查看JAR文件时,我可以看到其中列出的PropHolder.class

顺便说一下:我的本地机器上的代码运行正常。但是当我将一些脚本部署到Linux服务器上时,它无法工作。所以我认为这不是代码的问题。 但出于某种原因。部署过程很难跟踪。

可能是什么问题?

10 个答案:

答案 0 :(得分:174)

我最好的选择是这里有一个问题:

static {
    //code for loading properties from file
}

看起来会发生一些未捕获的异常,并传播到试图加载类的实际ClassLoader。我们需要一个堆栈跟踪来确认这一点。

在创建PropHolder.prop静态变量时发生了这种情况。

答案 1 :(得分:108)

您收到的java.lang.NoClassDefFoundError并不意味着您的班级缺失(在这种情况下,您将获得java.lang.ClassNotFoundException)。在尝试读取类时,ClassLoader在读取类定义时遇到错误。

在静态初始值设定项中放置一个try / catch并查看异常。如果您在那里阅读了一些文件并且它与您的本地环境不同,则很可能是问题的原因(可能找不到文件,没有权限等)。

答案 2 :(得分:30)

NoClassDefFoundError没有提供关于静态块内部出错的线索。最好在静态{...}初始化代码中始终有这样的块:

static {
  try {

    ... your init code here

  } catch (Throwable t) {
    LOG.error("Failure during static initialization", t);
    throw t;
  }
}

答案 3 :(得分:3)

我有同样的例外,这就是我解决问题的方法:

<强>前提条件:

  1. Junit类(和测试),扩展了另一个类。

  2. 使用spring初始化ApplicationContext,初始化项目。

  3. 应用程序上下文在@Before方法

  4. 中初始化

    <强>解决方案:

    从@BeforeClass方法初始化应用程序上下文,因为父类还需要从应用程序上下文中初始化的一些类。

    希望这会有所帮助。

答案 4 :(得分:1)

如上所述,这可能是一些事情。在我的情况下,我有一个静态初始化的变量,它依赖于我的属性文件中缺少的条目。在属性文件中添加了缺少的条目,问题解决了。

答案 5 :(得分:1)

我也有同样的例外-但只有在调试模式下运行时, 这是我解决问题的方式(整整3天后): 在build.gradle中,我有: 在defaultConfig部分中设置为“ multiDexEnabled true”。

        defaultConfig {
    applicationId "com.xxx.yyy"
    minSdkVersion 15
    targetSdkVersion 28
    versionCode 5123
    versionName "5123"
    // Enabling multidex support.
    multiDexEnabled true
}

但是显然这还不够。 但是当我改变时:

public class MyAppClass  extends Application 

收件人:

public class MyAppClass  extends MultiDexApplication 

这解决了它。 希望这会帮助某人

答案 6 :(得分:0)

就在几天前,我遇到了和你一样的问题。所有代码在我的本地机器上运行良好,但结果是错误(noclassdeffound&amp; initialize)。 所以我发布我的解决方案,但我不知道为什么,我只是提出了一个可能性。我希望有人知道会解释这个。@ John Vint 首先,我会告诉你我的问题。我的代码都有静态变量和静态块。当我第一次遇到这个问题时,我尝试了John Vint的解决方案,并尝试捕获异常。但是,我什么也没抓到。所以我认为这是因为静态变量(但现在我知道它们是相同的东西)并且仍然没有找到任何东西。 所以,我试着找到linux机器和我的电脑之间的区别。然后我发现只有当几个线程在一个进程中运行时才会出现这个问题(顺便说一下,linux机器有双核和双进程)。这意味着如果有两个任务(都使用具有静态块或变量的代码)在同一个进程中运行,则会出错,但如果它们在不同的进程中运行,则它们都可以。 在Linux机器上,我使用

mvn -U clean  test -Dtest=path 

运行一个任务,因为我的静态变量是启动一个容器(或者你初始化一个新的类加载器),所以它会一直停留到jvm停止,只有当一个进程中的所有任务都停止时,jvm才会停止。每个任务都会启动一个新的容器(或类加载器),这会让jvm感到困惑。结果,发生错误。 那么,如何解决呢?我的解决方案是向maven命令添加一个新命令,并使每个任务都转到同一个容器。

-Dxxx.version=xxxxx #sorry can't post more

也许你已经解决了这个问题,但仍然希望它会帮助那些遇到同样问题的人。

答案 7 :(得分:0)

如果您正在处理Android项目,请确保您没有在任何Android类上调用任何静态方法。我只使用JUnit + Mockito,所以也许其他一些框架可能会帮助你完全避免这个问题,我不确定。

我的问题是将Uri.parse(uriString)作为单元测试的静态初始化程序的一部分。 Uri类是一个Android API,这就是为什么单元测试版本无法找到它。我将此值更改为null,一切都恢复正常。

答案 8 :(得分:0)

我遇到了同样的问题: java.lang.NoClassDefFoundError:无法初始化com.xxx.HttpUtils类

static {
    //code for loading properties from file
}

这是环境问题。这意味着 application.yml 中的属性不正确或为空!

答案 9 :(得分:0)

我遇到了同样的问题。我在静态块中初始化了一个bean对象,如下所示:

static {
    try{
        mqttConfiguration = SpringBootBeanUtils.<MqttConfiguration>getBean(MqttConfiguration.class);
    }catch (Throwable e){
        System.out.println(e);
    }
 }

仅由于我的bean对象初始化过程导致了NPE,所以我对此很麻烦。 因此,我认为您应该仔细检查静态代码块。