2

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.

Roman C
  • 49,761
  • 33
  • 66
  • 176
questions
  • 2,337
  • 4
  • 24
  • 39
  • How do you start your application? Could you please add the complete console command to your question? – Andreas Dolk Sep 26 '12 at 16:42
  • How are you running it? (Command, location in directory tree, etc.) It's potentially interesting you get the `abc/test/test.java` text. – Dave Newton Sep 26 '12 at 16:42
  • What is the value of the `lib` property? For use in the manifest Class-Path it needs to be a relative path (using forward slashes), relative to the location of the main JAR file, not an absolute path (like you would get from ``). I suggest you consider using the `manifestclasspath` task to massage your dependency classpath into the right format for use in a manifest. – Ian Roberts Sep 26 '12 at 16:58
  • @Andreas_D- I'm using `java -jar mcon.jar" with some other parameters. Also, I'm running it from the root directory of the project. – questions Sep 26 '12 at 17:02
  • @DaveNewton- I have changed class and package names for the question. Its the same class as "abc.test.Test" – questions Sep 26 '12 at 17:03
  • @IanRoberts- the value of `${lib}` is "lib" which is a folder inside the project root directory, so this can be one possible reason. How do I use `manifestclasspath`? – questions Sep 26 '12 at 17:07
  • Caused by is an exception which was a cause of throwing another exception. – Roman C Sep 26 '12 at 17:17
  • I've added an answer with more details on `manifestclasspath`. – Ian Roberts Sep 26 '12 at 17:26

6 Answers6

7

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

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

felvhage
  • 1,149
  • 8
  • 6
5

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.

Community
  • 1
  • 1
davidfmatheson
  • 3,539
  • 19
  • 27
1

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

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • My main class depends on `abc.test.Test` class which is inside a library, and I have included that library in my classpath. – questions Sep 26 '12 at 17:09
  • And does your `abc.test.Test` class depend on any other class?? You need to add them also to the `library`. – Rohit Jain Sep 26 '12 at 17:11
  • The above class in inside a library, and as per the error its not able to find the same class which is causing the exception. – questions Sep 26 '12 at 17:15
  • Actually I can't give you more valuable input, as you are using `Ant` buil file.. And I actually have no idea how a class is searched through an `Ant` build file.. Sorry.. May be you can look to other member's answer.. – Rohit Jain Sep 26 '12 at 17:21
1

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)

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
0

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.

Arnab Biswas
  • 4,495
  • 3
  • 42
  • 60
0

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.

Roman C
  • 49,761
  • 33
  • 66
  • 176