java NoClassDefFoundError 的可能原因

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12606477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:32:00  来源:igfitidea点击:

Possible reasons for NoClassDefFoundError

javaantbuildjar

提问by questions

I'm getting the following NoClassDefFoundError, which is weird because the class is already present in the library jar.

我得到以下内容NoClassDefFoundError,这很奇怪,因为该类已经存在于库 jar 中。

Exception in thread "main" java.lang.NoClassDefFoundError: abc/test/Test.java
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:795)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:144)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:382)
        at java.net.URLClassLoader.access0(URLClassLoader.java:75)
        at java.net.URLClassLoader.run(URLClassLoader.java:294)
        at java.net.URLClassLoader.run(URLClassLoader.java:288)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:327)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:795)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:144)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:382)
        at java.net.URLClassLoader.access0(URLClassLoader.java:75)
        at java.net.URLClassLoader.run(URLClassLoader.java:294)
        at java.net.URLClassLoader.run(URLClassLoader.java:288)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:327)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:432)
Caused by: java.lang.ClassNotFoundException: abc.test.Test
        at java.net.URLClassLoader.run(URLClassLoader.java:299)
        at java.net.URLClassLoader.run(URLClassLoader.java:288)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:327)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 25 more

This looks like its not able to find the same class which is causing the exception. I have also included the library path in ant build.xml, which can be verified below.

这看起来像它无法找到导致异常的同一个类。我还在 ant 中包含了库路径build.xml,可以在下面进行验证。

<property name="deps" value="${lib}/abclib/abclib-test.jar"/>

<target name="dist" depends="compile">
        <manifest file="${dist}/MANIFEST.MF">
            <attribute name="Main-Class" value="xyz.test.TestConfiguration" />
            <attribute name="Class-Path" value="${deps}"/>
        </manifest>
        <jar jarfile="${dist}/abc.jar" basedir="${build}/" manifest="${dist}/MANIFEST.MF" />
</target>

I'm lost, can someone at least guide me where should I look or what I might be doing wrong?

我迷路了,至少有人可以指导我应该看哪里或我可能做错了什么吗?

Also, can someone throw light, "Exception" and "Caused by". I'm not quite getting how are they two related.

另外,有人可以抛出“异常”和“由”引起的光。我不太明白他们两个有什么关系。

回答by davidfmatheson

There's a really good explanation of the difference between NoClassDefFoundErrorand ClassNotFoundExceptionin another SO entry:

对于另一个SO 条目之间NoClassDefFoundError和之间的区别,有一个非常好的解释:ClassNotFoundException

does not mean that the ... class is not in the CLASSPATH. Infact its quite the opposite. It means that the class ... was found by the ClassLoader however when trying to load the class, it ran into an error reading the class definition. This typically happens when the class in question has static blocks or members which use a Class that's not found by the ClassLoader. So to find the culprit, view the source of the class in question ... and look for code using static blocks or static members.

并不意味着 ... 类不在 CLASSPATH 中。事实上,它恰恰相反。这意味着类 ... 被 ClassLoader 找到,但是在尝试加载类时,它在读取类定义时遇到了错误。这通常发生在所讨论的类具有静态块或使用类加载器未找到的类的成员时。因此,要找到罪魁祸首,请查看相关类的源代码……并查找使用静态块或静态成员的代码。

You need to look at the code for Test.java and figure out what it imports and make sure those classes are on the classpath. You could post the code of Test.java if you need help tracking the classes down.

您需要查看 Test.java 的代码并找出它导入的内容并确保这些类位于类路径中。如果您需要帮助跟踪类,您可以发布 Test.java 的代码。

回答by felvhage

Initializing a static field with a functionmay cause a hard to unveil NoClassDefFoundError

用函数初始化静态字段可能会导致难以揭开NoClassDefFoundError

Example: when you do something like this:

示例:当您执行以下操作时:

public class SomePanel extends Panel {
    static int CALC_VALUE = ValueCalcUtils.calcValue();
    ...

...where

...在哪里

ValueCalcUtils.calcValue()

... may throw an Exception.

... 可能会抛出异常。

Then, when the Exception is thrown, this will happen:

然后,当抛出异常时,会发生这种情况:

  1. There will be one single Error indicating on the actual Problem(that ValueCalcUtils.calcValue()has thrown an Exception for some reason)
  2. Every subsequent try to create an instance of SomePanelwill throw a (misleading) NoClassDefFoundErrorfor SomePanel.
  1. 将有一个错误指示实际问题ValueCalcUtils.calcValue()由于某种原因引发了异常)
  2. 随后每次尝试创建 的实例SomePanel都会抛出(误导性的)NoClassDefFoundErrorfor SomePanel

This happens because the JVM will remember that SomePanelcould not be initialized the first time he tried to create the class definition, and therefore does "not have a class definition" (NoClassDefFoundError) for SomePanelwhen asked again.

发生这种情况是因为 JVM 会记住SomePanel在他第一次尝试创建类定义时无法初始化,因此在再次询问时没有“没有类定义”( NoClassDefFoundError) SomePanel

In a Wicket/Tomcat situation ...

在 Wicket/Tomcat 情况下......

I've had this exact Problem with a Wicket-Application on a Tomcat-Webserver. The Problem was, that the static Utils-Method relied on WicketApplication.get().

我在 Tomcat-Webserver 上的 Wicket-Application 遇到了这个确切的问题。问题是,静态 Utils-Method 依赖于WicketApplication.get().

Where this would work in most cases, it would lead to the described Problem when the Tomcat tried to restore old Sessions from the SessionStore on startup. Sometimes the Sessions contained serialized Instances of the Panel in Question. When initializing the Panel-Class there was an Exception because the WicketApplicationdid not yet exist on Tomcat startup. Later on we had alot of confusing NoClassDefFoundErrors for the Panel in our Application-Logs, without apparent reason.

在大多数情况下这会起作用,当 Tomcat 尝试在启动时从 SessionStore 恢复旧会话时,它会导致所描述的问题。有时,会话包含相关小组的序列化实例。初始化 Panel-Class 时出现异常,因为WicketApplication在 Tomcat 启动时尚不存在。后来我们NoClassDefFoundError在我们的应用程序日志中有很多令人困惑的面板,没有明显的原因。

We finally found the single appearance of the "root Error" in the tomcat-stderror.logfile, since it was the tomcat throwing the initial error on startup.

我们终于在 tomcat-stderror.log文件中找到了“root Error”的单一出现,因为它是 tomcat 在启动时抛出初始错误。

Hope this helps someone.

希望这可以帮助某人。

回答by Rohit Jain

There is a difference between ClassNotFoundExceptionand NoClassDefFoundError..

ClassNotFoundExceptionNoClassDefFoundError..之间有区别

While firstone denote that the classyou are using is not in your classpath

虽然first一个表示class您正在使用的不在您的classpath

Secondone denotes that, the classyou are using is in turn using another classthat is not in your classpath..

Secondone 表示,class您正在使用的反过来使用另一个class不在您的类路径中的..

So, the problem is not that you don't have your class in classpath.. But the problem is, the classeson which your class is dependent is not in your classpath.. Now, you need to check what all classes, does your class(the one used currently in your code) depends upon..

所以,问题不在于你的类路径中没有你的类..但问题是,classes你的类所依赖的不在你的类路径中..现在,你需要检查classes你的class(当前在您的代码中使用的一个)取决于..

回答by Ian Roberts

The Class-Pathentry in MANIFEST.MFhas a specific format, in particular the entries in the classpath must be relative URIs (relative to the location of the JAR that contains the manifest). Ant has a manifestclasspathtaskto help in constructing suitable classpaths.

Class-Path在条目MANIFEST.MF具有特定的格式,特别是在类路径中的条目必须相对URI(相对于包含清单中的JAR的位置)。Ant 有一项manifestclasspath任务来帮助构建合适的类路径。

<target name="dist" depends="compile">
    <property name="jar.location" location="${dist}/mcon.jar"/>
    <manifestclasspath property="manifest.class.path" jarfile="${jar.location}">
      <classpath>
        <pathelement location="${deps}" />
      </classpath>
    </manifestclasspath>
    <manifest file="${dist}/MANIFEST.MF">
        <attribute name="Main-Class" value="xyz.test.TestConfiguration" />
        <attribute name="Class-Path" value="${manifest.class.path}"/>
    </manifest>
    <jar jarfile="${jar.location}" basedir="${build}/" manifest="${dist}/MANIFEST.MF" />
</target>

This should set up the Class-Pathwith the correct format (presumably something like ../lib/abclib/abclib-test.jarin your example)

这应该Class-Path使用正确的格式设置(大概类似于../lib/abclib/abclib-test.jar您的示例)

回答by Arnab Biswas

NoClassDefFoundError means that the class was present during the compilation and not during the run time execution. So, as suggested by others you need to understand the classpath that is being used during the run time and not during compile time.

NoClassDefFoundError 意味着该类在编译期间存在,而不是在运行时执行期间存在。因此,正如其他人所建议的那样,您需要了解在运行时而不是在编译时使用的类路径。

回答by Roman C

NoClassDefFoundErrorthrown as a result that your classloader cannot load a definition of a class. Make sure the correct path of the class that is on the classpath is given. Check for the library is in classpath. Modify you MANIFEST.MFso that a library exist in Class-Path. Run java with the command line -cp switch to denote a library on the classpath.

NoClassDefFoundError抛出的结果是您的类加载器无法加载类的定义。确保给出了类路径上的类的正确路径。检查库是否在类路径中。修改您MANIFEST.MF以便库存在于Class-Path. 使用命令行 -cp 开关运行 java 以表示类路径上的库。