运行Java应用程序时,我得到NoClassDefFoundError
。这通常是什么原因?
答案 0 :(得分:722)
虽然这可能是由于编译时和运行时之间的类路径不匹配,但它不一定是真的。
在这种情况下,重要的是要保持两到三个不同的例外:
java.lang.ClassNotFoundException
此异常表示在类路径中找不到该类。这表明我们正在尝试加载类定义,并且该类在类路径中不存在。
java.lang.NoClassDefFoundError
此异常表示JVM在其内部类定义数据结构中查找了类的定义但未找到它。这与说它无法从类路径加载不同。通常这表明我们之前尝试从类路径加载一个类,但由于某种原因它失败了 - 现在我们正在尝试再次使用该类(因此需要加载它,因为它上次失败了),但是我们'甚至没有尝试加载它,因为我们之前没有加载它(并且合理地怀疑我们会再次失败)。较早的失败可能是ClassNotFoundException或ExceptionInInitializerError(表示静态初始化块中的失败)或任何其他问题。关键是,NoClassDefFoundError不一定是类路径问题。
答案 1 :(得分:235)
当您的代码所依赖的类文件存在于编译时但在运行时未找到时,会导致这种情况。查找构建时和运行时类路径的差异。
答案 2 :(得分:103)
以下是说明java.lang.NoClassDefFoundError
的代码。有关详细说明,请参阅Jared's answer。
NoClassDefFoundErrorDemo.java
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;
}
答案 3 :(得分:31)
我发现当使用在运行时找到的类的不兼容版本编译代码时,有时会出现NoClassDefFound错误。我记得的具体实例是apache轴库。在我的运行时类路径上实际上有2个版本,它正在拾取过时和不兼容的版本而不是正确的版本,导致NoClassDefFound错误。这是在命令行应用程序中我使用类似于此的命令。
set classpath=%classpath%;axis.jar
我能够通过使用以下方式获取正确的版本:
set classpath=axis.jar;%classpath%;
答案 4 :(得分:29)
Java中的NoClassDefFoundError
定义:
Java虚拟机无法在运行时找到编译时可用的特定类。
如果某个类在编译期间存在但在运行时期间在java类路径中不可用。
<强>示例:强>
NoClassDefFoundError的一个简单示例是类属于缺少的JAR文件,或者JAR没有被添加到类路径中,或者有时jar的名称已被某人更改,就像在我的情况下我的一位同事改变了tibco .jar进入tibco_v3.jar并且程序失败了java.lang.NoClassDefFoundError,我想知道什么是错的。
尝试使用显式的-classpath选项运行您认为可行的类路径,如果它正常工作,那么确定有人覆盖java类路径的短信号。
可能的解决方案:
资源:
答案 5 :(得分:7)
这是我到目前为止发现的best solution。
假设我们有一个名为org.mypackage
的包,其中包含类:
并且定义此包的文件存储在目录D:\myprogram
(在Windows上)或/home/user/myprogram
(在Linux上)下。
当我们调用Java时,我们指定要运行的应用程序的名称:org.mypackage.HelloWorld
。但是,我们还必须告诉Java在哪里查找定义包的文件和目录。因此,要启动该程序,我们必须使用以下命令:
答案 6 :(得分:6)
我正在Spring Framework使用Maven并在我的项目中解决了这个错误。
班级中存在运行时错误。我正在读取一个属性为整数,但是当它从属性文件中读取值时,其值为double。
Spring没有给我一个关于运行时失败的哪一行的完整堆栈跟踪。
它简单地说NoClassDefFoundError
。但是当我将它作为本机Java应用程序执行(将其从MVC中取出)时,它给出了ExceptionInInitializerError
这是真正的原因,这就是我如何跟踪错误。
@ xli的回答让我深入了解了我的代码中可能出现的问题。
答案 7 :(得分:5)
当运行时类加载器加载的类无法访问java rootloader已经加载的类时,我得到NoClassFoundError。因为不同的类加载器位于不同的安全域中(根据java),jvm将不允许在运行时加载器地址空间中解析已由rootloader加载的类。
使用'java -javaagent:tracer.jar [你的java ARGS]'运行你的程序
它生成显示已加载类的输出,以及加载类的加载器env。跟踪无法解决课程的原因非常有用。
// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5
import java.lang.instrument.*;
import java.security.*;
// manifest.mf
// Premain-Class: ClassLoadTracer
// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class
// java -javaagent:tracer.jar [...]
public class ClassLoadTracer
{
public static void premain(String agentArgs, Instrumentation inst)
{
final java.io.PrintStream out = System.out;
inst.addTransformer(new ClassFileTransformer() {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);
// dump stack trace of the thread loading class
Thread.dumpStack();
// we just want the original .class bytes to be loaded!
// we are not instrumenting it...
return null;
}
});
}
}
答案 8 :(得分:4)
NoClassDefFoundErrors
时,请仔细阅读... 一种有趣的情况是,您可能会遇到许多NoClassDefFoundErrors
:
throw
的{{1}}块中的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
}
}
将与NoClassDefError
一起从静态块ExceptionInInitializerError
中抛出。
当您在单元测试中看到RuntimeException
时,这尤其重要。
您可以在测试之间“共享” NoClassDefFoundErrors
块执行,但是初始的static
仅在一个测试用例中。第一个使用有问题的ExceptionInInitializerError
类。使用Example
类的其他测试用例只会抛出Example
。
答案 9 :(得分:3)
如果您有生成代码(EMF等),可能会有太多静态初始化程序占用所有堆栈空间。
请参阅Stack Overflow问题 How to increase the Java stack size? 。
答案 10 :(得分:2)
下面的技术帮了我很多次了:
System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());
其中TheNoDefFoundClass可能是&#34;丢失&#34;由于您偏爱程序使用的同一个库的旧版本。最常见的情况是,当客户端软件被部署到占主导地位的容器中时,它拥有自己的类加载器和大量最流行的库的古老版本。
答案 11 :(得分:1)
我通过禁用所有模块的preDexLibraries修复了我的问题:
dexOptions {
preDexLibraries false
...
答案 12 :(得分:1)
NoClassDefFoundError
,例如,受影响的类尝试从{ {1}}目录,但不存在。如果您没有抓住META-INF
,有时您将看不到完整的堆栈跟踪信息;为了克服这个问题,您可以为NoClassDefFoundError
临时使用catch
子句:
Throwable
答案 13 :(得分:0)
ClassNotFoundException 与 NoClassDefFoundError
静态与动态类加载
Static(Implicit) class loading
- 引用、实例化或继承的结果。
MyClass myClass = new MyClass();
Dynamic(Explicit) class loading
是 Class.forName()、loadClass()、findSystemClass() 的结果
MyClass myClass = (MyClass) Class.forName("MyClass").newInstance();
每个类都有一个使用 ClassLoader
的 loadClass(String name);
这就是为什么
explicit class loader uses implicit class loader
NoClassDefFoundError
是 explicit class loader
的一部分。 Error
保证在编译过程中出现了这个类,但现在
(在tun时间)它不存在
ClassNotFoundException
是 implicit class loader
的一部分。 Exception
在可以额外使用它的场景中具有弹性 - 例如反射。
答案 14 :(得分:0)
我遇到了这个错误,但无法找出基于该线程的解决方案,但自己解决了。
对于我的问题,我正在编译以下代码:
go mod vendor
然后我在类似于/ ProjectName / valentines的文件夹结构中编译此代码
编译正常,但尝试执行:package valentines;
import java.math.BigInteger;
import java.util.ArrayList;
public class StudentSolver {
public static ArrayList<Boolean> solve(ArrayList<ArrayList<BigInteger>> problems) {
//DOING WORK HERE
}
public static void main(String[] args){
//TESTING SOLVE FUNCTION
}
}
我收到了NoClassDefError。
要解决此问题,我只删除了:java StudentSolver
我不太精通Java程序包,但是我如何解决错误,如果其他人已经回答了它,但我无法解释我的问题,我对此感到抱歉。
答案 15 :(得分:0)
更新[https://www.infoq.com/articles/single-file-execution-java11/]:
在Java SE 11中,您可以选择启动一个源代码文件 直接进行,无需中间编译。为了您的方便, 这样,像您这样的新手就不必运行javac + java(当然, 让他们感到困惑,这是为什么。
答案 16 :(得分:0)
我在使用Liberty服务器的JavaEE中遇到了一个NoClassDefFoundError有趣的问题。我正在使用IMS资源适配器,而我的server.xml已经具有imsudbJXA.rar的资源适配器。 当我为imsudbXA.rar添加新适配器时,对于DLIException,IMSConnectionSpec或SQLInteractionSpec的实例对象,我将开始收到此错误。 我不知道为什么,但是通过仅使用imsudbXA.rar为我的工作创建了新的server.xml来解决了该问题。我确信在server.xml中使用多个资源适配器是可以的,我只是没有时间研究它。
答案 17 :(得分:0)
每个人都在谈论一些Java配置方面的内容,JVM问题等,在我的情况下,该错误与这些主题完全无关,并且具有非常简单且易于解决的原因:我的端点注释错误我的控制器(Spring Boot应用程序)。
答案 18 :(得分:0)
在我的情况下,由于JDK版本不匹配,导致出现此错误。当我尝试从Intelij运行该应用程序时无法正常工作,但是从命令行运行它就可以了。这是因为Intelij试图使用已设置的Java 11 JDK运行它,但在命令行上却使用Java 8 JDK运行它。在“文件”>“项目结构”>“项目设置”>“ Project SDK”下切换该设置后,它对我有用。
答案 19 :(得分:0)
我在尝试在 Tomcat/JBOSS 服务器上部署应用程序时遇到 NoClassDefFoundError。我使用不同的依赖项来解决这个问题,但一直遇到同样的错误。将所有 javax.* 依赖项标记为 pom.xml 中提供的,并且 war 字面上没有依赖项。问题仍然不断出现。
终于意识到 src/main/webapps/WEB-INF/classes 有 classes 文件夹被复制到我的战争中,所以复制这些类而不是编译类,因此没有依赖项更改可以解决问题。
因此,如果任何以前编译的数据被复制,请小心,删除类文件夹并重新编译后,它起作用了!..
答案 20 :(得分:0)
当我将另一个模块的Maven依赖项添加到我的项目时,出现了此错误,最终通过在程序的JVM选项中添加-Xss2m
解决了该问题(自JDK5.0起默认为1兆字节)。据认为该程序没有足够的堆栈来加载类。
答案 21 :(得分:0)
这也可能是因为您从IDE复制具有特定程序包名称的代码文件,并希望尝试使用终端运行它。您必须首先从代码中删除程序包名称。 这发生在我身上。
答案 22 :(得分:0)
当我没有在项目的Java Build Path的“ Order and Export”选项卡上导出类时,出现NoClassDefFound错误。确保在添加到项目的构建路径中的所有依赖项的“订单和导出”选项卡中打上对勾。参见Eclipse warning: XXXXXXXXXXX.jar will not be exported or published. Runtime ClassNotFoundExceptions may result。
答案 23 :(得分:0)
此错误可能是由未经检查的 Java版本要求引起的。
在我的情况下,通过使用SDKMAN!从Java 9切换到Java 8,我能够在构建高知名度的开源项目时解决此错误。
sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu
然后按照以下说明进行全新安装。
使用 Maven 作为构建工具时,在禁用测试的情况下执行 clean 'install'build 有时会很有帮助 - 通常也很有意义/强>
mvn clean install -DskipTests
现在已经构建并安装了所有,您可以继续运行测试。
mvn test
答案 24 :(得分:0)
就我而言,问题是Eclipse无法区分同一项目的两个不同副本。我有一个锁定在trunk(SVN版本控制)上,另一个一次在一个分支中工作。我尝试将工作副本中的一个更改作为JUnit测试用例,其中包括将私有内部类提取为自己的公共类,当它正在工作时,我打开项目的另一个副本来环顾其他一些需要更改的部分代码。在某些时候,NoClassDefFoundError
突然抱怨私人内部阶级不存在;双击堆栈跟踪将我带到错误的项目副本中的源文件。
关闭项目的主干副本并再次运行测试用例可以解决问题。
答案 25 :(得分:0)
如果有人因为java.lang.NoClassDefFoundError: org/apache/log4j/Logger
错误来到这里,在我的情况下它是因为我使用log4j 2而生成的(但是我没有添加它附带的所有文件),并且一些依赖库使用了log4j 1解决方案是添加Log4j 1.x网桥:log4j附带的jar log4j-1.2-api-<version>.jar
2. log4j 2 migration中的更多信息。
答案 26 :(得分:-1)
Java无法在运行时找到A类。 A类是来自不同工作空间的maven项目ArtClient。 所以我将ArtClient导入我的Eclipse项目。 我的两个项目是使用ArtClient作为依赖项。 我将库引用更改为这些项目的引用(构建路径 - >配置构建路径)。
问题消失了。
答案 27 :(得分:-1)
我遇到了同样的问题,而且我已经存了好几个小时了。
我找到了解决方案。在我的例子中,由于这个原因定义了静态方法。 JVM无法创建该类的另一个对象。
例如,
private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");
答案 28 :(得分:-6)
我从SRC库中删除了两个文件后收到此消息,当我把它们带回来时,我一直看到这个错误消息。
我的解决方案是:重启Eclipse。从那时起,我再没有看到这个消息: - )
答案 29 :(得分:-7)
确保此匹配符合module:app
和module:lib
:
android {
compileSdkVersion 23
buildToolsVersion '22.0.1'
packagingOptions {
}
defaultConfig {
minSdkVersion 17
targetSdkVersion 23
versionCode 11
versionName "2.1"
}