一个有趣的例子,你可能会看到很多 NoClassDefFoundErrors 当您: throw 一 RuntimeException 在 static 你们班的学生 Example 截取它(或者如果它只是无关紧要的,就像它被扔进了一个测试用例) 尝试创建此类的示例 Example ``` 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
}
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);
}
public class NoClassDefFoundErrorDemo {
public static void main(String[] args) {
try {
// The following line would throw ExceptionInInitializerError
SimpleCalculator calculator1 = new SimpleCalculator();
} catch (Throwable t) {
System.out.println(t);
}
// The following line would cause NoClassDefFoundError
SimpleCalculator calculator2 = new SimpleCalculator();
}
}
simplecalculator.java
public class SimpleCalculator {
static int undefined = 1 / 0;
}
17条答案
按热度按时间hmae6n7t1#
这是由于存在代码所依赖的类文件,并且该类文件在编译时存在,但在运行时找不到。查找构建时和运行时类路径中的差异。
dtcbnfnu2#
一个有趣的例子,你可能会看到很多
NoClassDefFoundErrors
当您:throw
一RuntimeException
在static
你们班的学生Example
截取它(或者如果它只是无关紧要的,就像它被扔进了一个测试用例)尝试创建此类的示例
Example
```static class Example {
static {
thisThrowsRuntimeException();
}
}
static class OuterClazz {
}
```
NoClassDefError
将伴随着ExceptionInInitializerError
从静态块RuntimeException
.当你看到
NoClassDefFoundErrors
在单元测试中。在某种程度上你是在“分享”
static
在测试之间阻止执行,但初始ExceptionInInitializerError
只在一个测试用例中。第一个使用有问题的Example
班级。使用Example
全班只会扔NoClassDefFoundErrors
.pes8fvy93#
NoClassDefFoundError
当静态初始值设定项尝试加载在运行时不可用的资源束(例如受影响的类尝试从META-INF
目录,但不存在。如果你抓不到NoClassDefFoundError
,有时无法看到完整的堆栈跟踪;为了克服这个问题,你可以暂时使用catch
条款Throwable
:ibps3vxo4#
java中的noclassdeffounderror
定义:
java虚拟机无法在运行时找到编译时可用的特定类。
如果类在编译时存在,但在运行时在java类路径中不可用。
示例:
类不在类路径中,没有确定的方法知道它,但是很多时候你可以只看一下打印system.getproperty(“java.classpath”),它会打印类路径,从那里你至少可以了解实际的运行时类路径。
noclassdeffounderror的一个简单例子是类属于一个丢失的jar文件,或者jar没有添加到类路径中,或者有时jar的名称被某人更改了,比如在我的例子中,我的一个同事将tibco.jar更改为tibco\u v3.jar,程序在java.lang.noclassdeffounderror中失败,我想知道出了什么问题。
只要试着用显式的classpath选项运行你认为有效的类路径,如果它有效的话,那么这肯定是有人正在重写java类路径的一个短暂的信号。
jar文件上的权限问题也会导致java中的noclassdeffounderror。
xml配置上的输入错误也会导致java中的noclassdeffounderror。
当在包中定义的已编译类在加载时不在同一个包中时(如japplet),它将在java中抛出noclassdeffounderror。
可能的解决方案:
该类在java类路径中不可用。
如果您在j2ee环境中工作,那么类在多个类加载器之间的可见性也会导致java.lang.noclassdeffounderror,有关详细讨论,请参阅示例和场景部分。
检查日志文件中的java.lang.exceptionininitializererror。由于静态初始化失败而导致的noclassdeffounderror非常常见。
因为noclassdeffounderror是java.lang.linkageerror的一个子类,如果其中一个依赖项(如本机库)可能不可用,它也会出现。
任何启动脚本都将重写classpath环境变量。
您可能正在使用jar命令运行程序,但清单文件的classpath属性中没有定义类。
资源:
解决noclassdeffounderror的3种方法
java.lang.noclassdeffounderror问题模式
wnavrhmk5#
下面的技巧帮助了我很多次:
其中,thenodeffoundclass是由于偏爱程序使用的同一库的旧版本而可能“丢失”的类。当客户端软件被部署到一个主要的容器中时,这种情况最常发生,该容器配备有自己的类加载器和大量最流行的libs的古老版本。
aor9mmx16#
此错误可能由未经检查的java版本要求引起。
在我的例子中,通过使用sdkman!从java9切换到java8,我在构建一个引人注目的开源项目时解决了这个错误!。
然后按如下所述进行清洁安装。
当使用maven作为构建工具时,它有时是有用的——而且是常见的
44u64gxh7#
同一项目的两个不同 checkout 副本
在我的例子中,问题是eclipse无法区分同一项目的两个不同副本。我有一个锁在 Backbone.js 上(svn版本控制),另一个一次在一个分支上工作。我将工作副本中的一个更改作为junit测试用例进行了尝试,其中包括将私有内部类提取为公共类,在它工作时,我打开项目的另一个副本,查看需要更改的代码的其他部分。在某个时候
NoClassDefFoundError
突然出现抱怨私人内部阶级不在那里;双击堆栈跟踪会找到错误项目副本中的源文件。关闭项目的 Backbone.js 副本并再次运行测试用例解决了这个问题。
mrfwxfqh8#
我在maven中使用spring框架,并在我的项目中解决了这个错误。
类中存在运行时错误。我将属性读取为整数,但当它从属性文件中读取值时,它的值是双精度的。
spring没有给出运行时在哪一行失败的完整堆栈跟踪。它只是说
NoClassDefFoundError
. 但是当我把它作为一个本机java应用程序执行时(把它从mvc中去掉),它给出了ExceptionInInitializerError
哪个是真正的原因,哪个是我追踪错误的方式。@xli的回答让我深入了解了代码中可能存在的错误。
jgwigjjp9#
这是迄今为止我找到的最好的解决办法。
假设我们有一个叫
org.mypackage
包含类:helloworld(主类)
支持类
实用类
定义这个包的文件物理上存储在这个目录下
D:\myprogram
(在窗口上)或/home/user/myprogram
(在linux上)。文件结构如下所示:
调用java时,我们指定要运行的应用程序的名称:
org.mypackage.HelloWorld
. 但是,我们还必须告诉java在哪里查找定义包的文件和目录。所以要启动程序,我们必须使用以下命令:bq9c1y6610#
我发现,有时在使用运行时发现的类的不兼容版本编译代码时,会出现noclassdeffound错误。我记得的具体示例是apacheaxis库。实际上,在我的运行时类路径上有两个版本,它检测到的是过时的和不兼容的版本,而不是正确的版本,这导致了noclassdeffound错误。这是在一个命令行应用程序中,我使用的命令与此类似。
我可以通过使用以下方法使其获得正确的版本:
guykilcj11#
下面是要说明的代码
java.lang.NoClassDefFoundError
. 详细解释请参见jared的回答。noclassdeffounderrordemo.java文件
simplecalculator.java
nue99wik12#
当运行时类加载器加载的类无法访问java rootloader已经加载的类时,我得到noclassfounderror。因为不同的类加载器位于不同的安全域(根据java),jvm不允许rootloader已经加载的类在运行时加载器地址空间中解析。
用“java”运行程序-javaagent:tracer.jar [您的java参数]'
它生成显示加载的类和加载该类的loader env的输出。跟踪类无法解析的原因非常有用。
mrphzbgm13#
当我将另一个模块的maven依赖项添加到我的项目中时,我遇到了这个错误,这个问题最终通过add解决了
-Xss2m
添加到我的程序的jvm选项(自jdk5.0以来,默认值是1兆字节)。据信程序没有足够的堆栈来加载类。d5vmydt914#
我通过禁用所有模块的predexlibraries修复了我的问题:
kcrjzv8t15#
虽然这可能是由于编译时和运行时之间的类路径不匹配造成的,但这不一定是真的。
在这种情况下,我们必须清楚地记住两个或三个不同的例外:
java.lang.ClassNotFoundException
此异常表示在类路径上找不到该类。这表明我们试图加载类定义,而类路径上不存在该类。java.lang.NoClassDefFoundError
此异常表示jvm在其内部类定义数据结构中查找类的定义,但没有找到它。这不同于说它不能从类路径加载。通常这表示我们以前试图从类路径加载一个类,但是由于某种原因失败了——现在我们尝试再次使用这个类(因此需要加载它,因为它上次失败了),但是我们甚至不打算加载它,因为我们之前加载它失败了(并且合理地怀疑我们会再次失败)。早期的故障可能是classnotfoundexception或exceptionininitializererror(表示静态初始化块中的故障)或任何其他问题。关键是,noclassdeffounderror不一定是类路径问题。