2

我得到以下内容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.access$100(URLClassLoader.java:75)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:294)
        at java.net.URLClassLoader$1.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.access$100(URLClassLoader.java:75)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:294)
        at java.net.URLClassLoader$1.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$1.run(URLClassLoader.java:299)
        at java.net.URLClassLoader$1.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

看起来它无法找到导致异常的同一类。我还在 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>

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

另外,有人可以抛出灯,“异常”和“由”引起。我不太明白他们两个是如何相关的。

4

6 回答 6

7

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

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

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

...在哪里

ValueCalcUtils.calcValue()

...引发异常。

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

  1. 将有一个错误指示实际问题ValueCalcUtils.calcValue()由于某种原因引发了异常)
  2. SomePanel随后每次尝试NoClassDefFoundError创建SomePanel.

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

在 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().

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 WicketApplication did not yet exist on Tomcat startup. Later on we had alot of confusing NoClassDefFoundErrors for the Panel in our Application-Logs, without apparent reason.

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

希望这可以帮助某人。

于 2013-11-14T10:13:09.217 回答
5

对另一个SO 条目NoClassDefFoundError之间的区别有一个很好的解释:ClassNotFoundException

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

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

于 2012-09-26T17:44:48.560 回答
1

ClassNotFoundExceptionNoClassDefFoundError..之间有区别

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

Second一个表示,class您正在使用的又是另一个class不在您的类路径中的..

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

于 2012-09-26T16:43:56.467 回答
1

中的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>

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

于 2012-09-26T17:26:31.080 回答
0

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

于 2012-09-26T16:58:06.807 回答
0

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

于 2012-09-26T17:07:16.627 回答