Possible reasons for NoClassDefFoundError

六月ゝ 毕业季﹏ 提交于 2019-12-12 19:14:31

问题


I'm getting the following NoClassDefFoundError, which is weird because the class is already present in the library 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

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.

<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.


回答1:


There's a really good explanation of the difference between NoClassDefFoundError and ClassNotFoundException in another SO entry:

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.

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.




回答2:


Initializing a static field with a function may cause a hard to unveil 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 SomePanel will throw a (misleading) NoClassDefFoundError for SomePanel.

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

In a Wicket/Tomcat situation ...

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.

Hope this helps someone.




回答3:


There is a difference between ClassNotFoundException and NoClassDefFoundError..

While first one denote that the class you are using is not in your classpath

Second one denotes that, the class you are using is in turn using another class that is not in your classpath..

So, the problem is not that you don't have your class in classpath.. But the problem is, the classes on 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..




回答4:


The Class-Path entry in MANIFEST.MF has 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 manifestclasspath task to help in constructing suitable classpaths.

<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-Path with the correct format (presumably something like ../lib/abclib/abclib-test.jar in your example)




回答5:


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.




回答6:


NoClassDefFoundError thrown 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.MF so that a library exist in Class-Path. Run java with the command line -cp switch to denote a library on the classpath.



来源:https://stackoverflow.com/questions/12606477/possible-reasons-for-noclassdeffounderror

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!