繁体   English   中英

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

[英]java.lang.NoClassDefFoundError: Could not initialize class XXX

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列出的PropHolder.class

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

可能是什么问题呢?

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

static {
    //code for loading properties from file
}

似乎发生了一些未捕获的异常,并传播到尝试加载类的实际 ClassLoader。 不过,我们需要一个堆栈跟踪来确认这一点。

在创建PropHolder.prop静态变量时发生。

你得到一个java.lang.NoClassDefFoundError这并不意味着你的类丢失了(在这种情况下你会得到一个java.lang.ClassNotFoundException )。 ClassLoader 在尝试读取类时读取类定义时遇到错误。

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

NoClassDefFoundError 并没有提供关于静态块内部出了什么问题的太多线索。 在 static { ... } 初始化代码中总是有这样的块是一种很好的做法:

static {
  try {

    ... your init code here

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

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

先决条件:

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

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

  3. 应用程序上下文在@Before 方法中初始化

解决方案:

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

希望这会有所帮助。

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

就在几天前,我遇到了和你一样的问题。 所有代码在我的本地机器上运行良好,但结果是错误(noclassdeffound&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

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

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

我的问题是调用Uri.parse(uriString)作为单元测试的静态初始值设定项的一部分。 Uri 类是一个 Android API,这就是单元测试构建找不到它的原因。 我改为将此值更改为null ,一切都恢复正常。

我有同样的例外 - 但仅在调试模式下运行时,这就是我解决问题的方式(整整 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 

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

我有同样的问题: java.lang.NoClassDefFoundError: could not initialize class com.xxx.HttpUtils

static {
    //code for loading properties from file
}

是环境问题,就是application.yml里面的属性不正确或者是空的!

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

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

仅仅因为我的 bean 对象初始化过程导致了 NPE,我就遇到了麻烦。 所以我认为你应该仔细检查你的静态代码块。

添加这些导入语句解决了这个问题:

import org.junit.runner.RunWith;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM