如何解决java.lang.NoClassDefFoundError?

我已经在Oracle的Java教程中尝试了这个例子。 他们都编译好,但在运行时,都提出了这个错误:

Exception in thread "main" java.lang.NoClassDefFoundError: graphics/shapes/Square at Main.main(Main.java:7) Caused by: java.lang.ClassNotFoundException: graphics.shapes.Square at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 1 more 

我想我可能有错误的文件夹中的Main.java文件。 这是目录层次结构:

 graphics ├ Main.java ├ shapes | ├ Square.java | ├ Triangle.java ├ linepoint | ├ Line.java | ├ Point.java ├ spaceobjects | ├ Cube.java | ├ RectPrism.java 

这里是Main.java

 import graphics.shapes.*; import graphics.linepoint.* import graphics.spaceobjects.*; public class Main { public static void main(String args[]) { Square s = new Square(2,3,15); Line l = new Line(1,5,2,3); Cube c = new Cube(13,32,22); } } 

我在这里做错了什么?

UPDATE

在我把把Main类放到graphics包(我添加了package graphics;把它),设置类path为“_test”(包含graphics的文件夹),编译它,并运行它使用java graphics.Main (从命令行), 有效。

真的晚了更新#2

我没有使用Eclipse(只是Notepad ++和JDK),上述更新解决了我的问题。 然而,似乎很多答案都是针对Eclipse和IntelliJ的,但它们有相似的概念。

编译完代码后,最终会在程序中为每个类添加.class文件。 这些二进制文件是Java解释执行你的程序的字节码。 NoClassDefFoundError指示负责dynamic加载类的类加载器(本例中为java.net.URLClassLoader )找不到要尝试使用的类的.class文件。

如果所需的类不存在,则代码将无法编译(除非类使用reflection进行加载),所以通常此exception意味着您的类path不包含所需的类。 请记住,类加载器(特别是java.net.URLClassLoader )将在类path的每个条目中的文件夹a / b / c /中的程序包abc中查找类。 NoClassDefFoundError也可以表明你错过了一个.jar文件的传递依赖关系,这个依赖关系是你编译的,你正在尝试使用。

例如,如果您有一个类com.example.Foo ,编译后您将有一个类文件Foo.class 。 比如说你的工作目录是.../project/ 。 该类文件必须放置在.../project/com/example ,并且将类path设置为.../project/

附注:我build议您利用Java和JVM语言中的惊人工具。 像Eclipse和IDEA这样的现代IDE,以及像Maven或Gradle这样的构buildpipe理工具将帮助您不必担心类path(尽可能多的)并关注代码! 也就是说, 这个链接解释了如何在命令行上执行时设置类path。

我想在NoClassDefFoundError上更正其他人的观点。

NoClassDefFoundError可能由于多种原因而发生

  1. ClassNotFoundException – 找不到该引用类的.class,而不pipe它在编译时是否可用(即基类/子类)。
  2. find类文件,但在初始化静态variables时引发exception
  3. 类文件位于,初始化静态块时引发exception

在原始问题中,可以通过将CLASSPATH设置为引用的类jar文件或其包文件夹来纠正这种情况。

说“在编译时可用”是什么意思?

  • 引用的类用于代码中。
    例如:两个类,A和B(延伸到A)。 如果B在代码中被直接引用,它在编译时可用,即A a = new B();

说“在编译时不可用”是什么意思?

  • 编译时间类和运行时间类是不同的,例如,基类是使用子类的类名加载的,例如Class.forName(“classname”)
    例如:两个类,A和B(延伸到A)。 代码有
    A = Class.forName(“B”)。newInstance();

NoClassDefFoundError表示该类在Compile time存在于类path中,但在Runtime的类path中不存在。

如果您使用的是Eclipse,请确保在.classpath文件中包含shapeslinepointsspaceobjects作为条目。

如果对于添加到项目中的某个外部jar文件获取了NoClassDefFoundError,请尝试在lib文件夹中添加该jar文件,并通过属性>> Java Build Path >>添加variables>>configurationvariables>> New将其添加到类path中variablesinput。 并重build。

如果在编译和运行时遇到以下错误之一:

  • 的NoClassDefFoundError

  • 错误:无法find或加载主类hello

  • java.lang.ClassLoader.defineClass1(Native Method)java.lang.ClassLoader.defineClass(Unknown Source)在线程“main”中的exceptionjava.lang.NoClassDefFoundError:javaTest / test / hello(错误名称:test / hello)at java.net.URLClassLoader.access上的java.net.URLClassLoader.defineClass(Unknown Source)上的java.security.SecureClassLoader.defineClass(Unknown Source)在java.net.URLClassLoader $ 1.run(Unknown Source)上的$ 100 java.net.URLClassLoader在java.lang.ClassLoader.loadClass(Unknown Source)处于java.net.URLClassLoader.findClass(Unknown Source)处的java.security.AccessController.doPrivileged(Native方法)处获得$ 1.run(Unknown Source) .misc.Launcher $ AppClassLoader.loadClass(Unknown Source)at java.lang.ClassLoader.loadClass(Unknown Source)at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

————————– SOLUTIION ———————–

问题主要在软件包组织方面。 您应该根据源代码中的包类别妥善安排文件夹中的类。

 On Compiling process use this command: javac -d . [FileName.java] To Run the class please use this command: java [Package].[ClassName] 
 java.lang.NoClassDefFoundError 

表示在编译 发现了某些东西,但在运行 时却没有。 也许你只需要将它添加到类path。

在重大重构之后,这有时会发生在IntelliJ IDEA中。

右键单击您的项目,然后select – >编译模块 ,然后重新启动项目,它应该再次工作。

在类path中找不到预期的类时,不会发生类定义exception 。 在编译时间类:类是从Java编译器生成的,但不知何故在运行时找不到从属类。

让我们通过一个简单的例子:

 public class ClassA{ public static void main(String args[]){ //Some gibberish Code... String text = ClassB.getString(); System.out.println("Text is :" + text); } 

}

 public class ClassB{ public static String getString(){ return "Testing Some Exception"; } } 

现在让我们假设上面的两个Java源代码放在一些文件夹让我们说“NoClassDefinationFoundExceptionDemo”

现在打开一个shell(假设Java已经正确安装)

  1. 转到文件夹“NoClassDefinationFoundExceptionDemo”
  2. 编译Java源文件javac ClassB javac ClassA
  3. 两个文件都编译成功,并生成与ClassA.class和ClassB.class相同的文件夹中的Class文件
  4. 现在,由于我们将ClassPath过滤为当前工作目录,因此我们执行以下命令java -cp。 ClassA和它成功地工作,你会看到屏幕上的输出
  5. 现在让我们说,你从现在的目录中删除了ClassB.class文件。 现在再次执行该命令。 java -cp。 ClassA现在,它会用NoClassDefFoundException来迎接你。 因为ClassB是ClassA的依赖关系,在类path(即当前工作目录)中找不到。

Java中的NoClassDefFoundError:

定义:

NoClassDefFoundError将在编译期间出现,但在运行时在java classpath中不可用。 通常情况下,当你得到NoClassDefFoundError时,你会在日志中看到下面一行:线程“main”中的exceptionjava.lang.NoClassDefFoundError

可能的原因:

  1. 该类在Java Classpath中不可用。

  2. 您可能正在使用jar命令运行您的程序,并且未在清单文件的ClassPath属性中定义类。

  3. 任何启动脚本都将重写Classpath环境variables。

  4. 因为NoClassDefFoundError是java.lang.LinkageError的一个子类,所以如果像本地库这样的依赖项之一可能不可用的话,它也会出现。

  5. 检查日志文件中的java.lang.ExceptionInInitializerError。 由于静态初始化失败而导致的NoClassDefFoundError非常普遍。

  6. 如果你在J2EE环境下工作的可见性比Class中的多个Classloader还可能导致java.lang.NoClassDefFoundError,请参阅示例和场景部分进行详细讨论。

可能的决议:

  1. validation所有必需的Java类都包含在应用程序的类path中。 在开始执行依赖于某些外部库的Java应用程序之前,最常见的错误是不包括所有必需的类。

  2. 应用程序的类path是正确的,但Classpath环境variables在应用程序执行之前被覆盖。

  3. validation前面提到的ExceptionInInitializerError没有出现在应用程序的堆栈跟踪中。

资源:

在Java J2EE中解决java.lang.NoClassDefFoundError的3种方法

java.lang.NoClassDefFoundError – 如何解决找不到类Def错误

如果你的项目是像com.blahcode这样的包,而你的类叫做Main ,编译后的文件可能会以./out/com/blahcode/Main.class这样的目录结构输出。 IntelliJ IDEA尤其如此。

当试图从一个shell或者cmd运行的时候,你需要cd到那个包含com的子目录。

 cd out java -classpath . com.blahcode.Main 

确保您正确键入类名称。 我得到这个错误,因为我没有用大写字母开始类名

在NetBeans项目上工作了好几个月之后,我突然收到一个“Low Memory”警告后很快就收到了NoClassDefFoundError消息。 做一个干净的重build没有帮助,但closuresNetbeans完全重新开放项目没有错误报告。

这个答案是特定于在服务中发生的java.lang.NoClassDefFoundError:

我的团队最近在升级提供服务的rpm后看到了这个错误。 rpm和它里面的软件都是用Maven编译的,所以看起来我们有一个编译时间的依赖关系,但是没有包含在rpm中。

但是,在调查时,找不到的类与堆栈跟踪中的几个类位于同一个模块中。 而且,这不是最近才被添加到构build中的模块。 这些事实表明它可能不是一个Maven依赖性问题。

最终的解决scheme: 重新启动服务!

看起来rpm升级使底层jar文件上的服务文件句柄失效。 然后服务看到一个没有被加载到内存中的类,在它的jar文件句柄列表中find它,并且因为它可以加载类的文件句柄已经失效而找不到它。 重新启动服务,迫使它重新加载所有的文件句柄,然后允许它加载在rpm升级之后在内存中找不到的那个类。

希望具体案件帮助某人。

呃..join类path后,我有相同的错误。 我find的解决scheme是删除我的项目的bin文件夹。 之后,该文件夹是只有清单文件自动创build…然后错误消失。

我希望它有帮助。

我在这条链上的两分钱:

确保类path包含完整path( /home/user/lib/some_lib.jar而不是~/lib/some_lib.jar ),否则您仍然可能会遇到NoClassDefFoundError错误。

当由运行时类加载器加载的类不能访问java根加载器已经加载的类时,我得到NoClassFoundError。 因为不同的类加载器处于不同的安全域(根据java),所以jvm将不允许已经由根加载器加载的类在运行时加载器地址空间中被parsing。

用'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; } }); } } 

我的genymotion设备发生了很多事情。 确保安装Genymotion的驱动器上有足够的可用内存。

这发生在Android Studio中。

为我工作的解决scheme:只需重新启动工作室。

我使用Android studio时遇到了与我的Android开发相同的问题。 提供的解决scheme是一般的,并没有帮助我(至less对我而言)。 经过数小时的研究,我发现了以下解决scheme,并可能有助于Android开发人员使用android studio进行开发。 修改设置如下Preferences – > Build,Execution,Deployment – > Instant Run – >取消选中第一个选项。

有了这个变化,我正在运行。 希望这会帮助我的开发者朋友。

检查你的类中是否有静态处理程序,如果是,请删除它或更改你的代码,导致静态处理程序只能在主线程中启动,崩溃可能以这种方式触发:

1.首先在非主线程中创build类的实例并捕获崩溃。

2.然后在主线程中调用Class的字段方法,会得到NoClassDefFoundError。

这里是testing代码:

 public class MyClass{ private static Handler mHandler = new Handler(); public static int num = 0; 

}

在你主要活动的onCrete方法中,添加testing代码部分:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //test code start new Thread(new Runnable() { @Override public void run() { try { MyClass myClass = new MyClass(); } catch (Throwable e) { e.printStackTrace(); } } }).start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } MyClass.num = 3; // end of test code } 

有一个简单的方法来解决它使用handlerThread init处理程序:

 private static Handler mHandler; private static HandlerThread handlerThread = new HandlerThread("newthread"); static { handlerThread.start(); mHandler = new Handler(handlerThread.getLooper(), mHandlerCB); } 

如果你使用多个模块,你应该有

dexOptions { preDexLibraries = false }

在你的构build文件中。

我在使用Apache Axis时遇到了这个问题。 花费了几个小时,根据大部分的反馈和类似的线程来处理classpath / buildconfiguration。 事实certificate,我错过了某些Web服务事务所必需的支持XML库。 把它们添加到项目中,一切都变好了

(1)第一种方法:我解决了这个问题通过删除一些Dependencies类从下面的代码中删除这个问题,我遇到了4.2.2

 compile 'com.google.android.gms:play-services-gcm:11.0.4' compile 'com.google.android.gms:play-services:11.0.4' 

这些额外的我的代码,我删除了他们

  dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile files('libs/ypylibs.jar') compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.google.android.gms:play-services-gcm:11.0.4' compile 'com.google.android.gms:play-services:11.0.4' compile 'com.google.android.gms:play-services-ads:11.0.4' compile 'com.dailymotion.dailymotion-sdk-android:sdk:0.1.12' compile 'org.apache.httpcomponents:httpcore:4.4.1' compile 'commons-io:commons-io:1.3.2' compile 'com.oguzdev:CircularFloatingActionMenu:1.0.2' compile 'com.android.support:multidex:1.0.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' 

}

(2)方法:解决这个问题的另一种方法是创build一个新的类MyApplication

 public class MyApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } 

}

然后将其添加到mainfest文件和应用程序标记中

  <application android:allowBackup="true" android:name=".gps.navigation.map.MyApplication" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"></application> 

在你的主要活动之后,如果需要删除appcompactactivity,并扩展你的课程活动,那么将起作用。

这个exception的一个错误来源可能是由于Proguard的定义不一致造成的,例如缺失

-libraryJars“path.to.a.missing.jar.library”。

这解释了为什么编译和运行正常,因为jar在那里,而清洁和生成失败。 记得在proguard setup中定义新添加的jar库!

请注意,来自Proguard的错误消息实际上不符合标准,因为当jar完全不在时,它们很容易与类似的ant消息混淆。 只有在最底层才会有一点麻烦的进步。 因此,开始寻找传统的类path错误等是相当逻辑的,但是这将是徒劳的。

很显然,NoClassDefFoundexception将是运行时的结果,例如生成的可执行jar文件,并且缺乏一致性。 有人把它叫做“地狱”