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

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

public class PropHolder {

public static Properties prop;

static {

//code for loading properties from file

}

}

// Referencing the class somewhere else:

Properties prop = PropHolder.prop;

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

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

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

可能是什么问题呢?

8个解决方案

156 votes

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

static {

//code for loading properties from file

}

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

创建PropHolder.prop静态变量时发生的情况。

John Vint answered 2019-05-28T06:33:31Z

100 votes

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

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

jeha answered 2019-05-28T06:34:05Z

25 votes

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

static {

try {

... your init code here

} catch (Throwable t) {

LOG.error("Failure during static initialization", t);

throw t;

}

}

Mark Hansen answered 2019-05-28T06:34:34Z

2 votes

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

前提条件:

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

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

Application上下文在@Before方法中初始化

解:

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

希望这会有所帮助。

KerenSi answered 2019-05-28T06:35:46Z

0 votes

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

TriMix answered 2019-05-28T06:36:15Z

0 votes

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

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

MonkeyKing answered 2019-05-28T06:37:01Z

0 votes

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

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

lifeson106 answered 2019-05-28T06:37:38Z

0 votes

我有相同的异常 - 但只有在调试模式下运行时,这就是我解决问题的方法(整整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

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

Elad answered 2019-05-28T06:38:30Z

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值