当我运行Java应用程序时,我得到了一个NoClassDefFoundError。造成这种情况的典型原因是什么?
当前回答
对此,我的解决方案是为缺失的特定类“利用”类路径内容。在我的情况下,我有2个依赖项,虽然我能够成功地编译使用javac…,我不能运行产生的类文件使用java…,因为BouncyCastle jar中的Dynamic类不能在运行时加载。
javac --classpath "ext/commons-io-2.11.0;ext/bc-fips-1.0.2.3" hello.java
因此在编译时和运行时,JVM知道在哪里获取Apache Commons和BouncyCastle依赖项,然而,当运行这个时,我得到了
Error: Unable to initialize main class hello
Caused by: java.lang.NoClassDefFoundError:
org/bouncycastle/jcajce/provider/BouncyCastleFipsProvider
因此,根据类路径,我在相同的位置手动创建了一个名为ext的新文件夹,然后在其中放置了BouncyCastle jar,以确保在运行时可以找到它。只要结果清单中指定了jar的位置,您就可以将jar相对于类文件或jar文件放置。注意,我只需要利用包含丢失类文件的一个jar。
其他回答
有一个有趣的例子,你可能会看到很多NoClassDefFoundErrors:
在类的静态块中抛出一个RuntimeException 拦截它(或者如果它在测试用例中抛出并不重要) 尝试创建该类的实例
static class Example {
static {
thisThrowsRuntimeException();
}
}
static class OuterClazz {
OuterClazz() {
try {
new Example();
} catch (Throwable ignored) { //simulating catching RuntimeException from static block
// DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
}
new Example(); //this throws NoClassDefFoundError
}
}
NoClassDefError将伴随来自静态块RuntimeException的ExceptionInInitializerError一起抛出。
当你在UNIT TESTS中看到NoClassDefFoundErrors时,这一点尤其重要。
在某种程度上,您在测试之间“共享”静态块执行,但初始的ExceptionInInitializerError将仅在一个测试用例中。第一个使用有问题的Example类。其他使用Example类的测试用例只会抛出NoClassDefFoundErrors。
I have had an interesting issue wiht NoClassDefFoundError in JavaEE working with Liberty server. I was using IMS resource adapters and my server.xml had already resource adapter for imsudbJXA.rar. When I added new adapter for imsudbXA.rar, I would start getting this error for instance objects for DLIException, IMSConnectionSpec or SQLInteractionSpec. I could not figure why but I resolved it by creating new server.xml for my work using only imsudbXA.rar. I am sure using multiple resource adapters in server.xml is fine, I just had no time to look into that.
Java无法在运行时找到类A。 Class A在maven项目ArtClient中,来自不同的工作空间。 因此,我将ArtClient导入到Eclipse项目中。 我的两个项目使用ArtClient作为依赖项。 我将这些库引用更改为项目引用(构建路径->配置构建路径)。
问题就这样解决了。
当静态初始化器试图加载一个在运行时不可用的资源包时,也会发生NoClassDefFoundError,例如受影响的类试图从META-INF目录加载一个属性文件,但不存在。如果你没有捕获NoClassDefFoundError,有时你将无法看到完整的堆栈跟踪;为了克服这个问题,你可以临时为Throwable使用一个catch子句:
try {
// Statement(s) that cause(s) the affected class to be loaded
} catch (Throwable t) {
Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}
我发现,当使用运行时发现的不兼容的类版本编译代码时,有时会得到NoClassDefFound错误。我记得的具体实例是apache axis库。在我的运行时类路径上实际上有2个版本,它正在挑选过时和不兼容的版本,而不是正确的版本,导致NoClassDefFound错误。这是在一个命令行应用程序中,我正在使用类似的命令。
set classpath=%classpath%;axis.jar
我能够让它拿起正确的版本使用:
set classpath=axis.jar;%classpath%;
推荐文章
- 到底是什么导致了堆栈溢出错误?
- 为什么Android工作室说“等待调试器”如果我不调试?
- Java:路径vs文件
- ExecutorService,如何等待所有任务完成
- Maven依赖Servlet 3.0 API?
- 如何在IntelliJ IDEA中添加目录到应用程序运行概要文件中的类路径?
- getter和setter是糟糕的设计吗?相互矛盾的建议
- Android room persistent: AppDatabase_Impl不存在
- Java的String[]在Kotlin中等价于什么?
- Intellij IDEA上的System.out.println()快捷方式
- 使用Spring RestTemplate获取JSON对象列表
- Spring JPA选择特定的列
- URLEncoder不能翻译空格字符
- Java中的super()
- 如何转换JSON字符串映射<字符串,字符串>与杰克逊JSON