What Causes and What Are the Differences Between Noclassdeffounderror and Classnotfoundexception

What causes and what are the differences between NoClassDefFoundError and ClassNotFoundException?

The difference from the Java API Specifications is as follows.

For ClassNotFoundException:

Thrown when an application tries to
load in a class through its string
name using:

  • The forName method in class Class.
  • The findSystemClass method in class ClassLoader.
  • The loadClass method in class ClassLoader.

but no definition for the class with
the specified name could be found.

For NoClassDefFoundError:

Thrown if the Java Virtual Machine or
a ClassLoader instance tries to load
in the definition of a class (as part
of a normal method call or as part of
creating a new instance using the new
expression) and no definition of the
class could be found.

The searched-for class definition
existed when the currently executing
class was compiled, but the definition
can no longer be found.

So, it appears that the NoClassDefFoundError occurs when the source was successfully compiled, but at runtime, the required class files were not found. This may be something that can happen in the distribution or production of JAR files, where not all the required class files were included.

As for ClassNotFoundException, it appears that it may stem from trying to make reflective calls to classes at runtime, but the classes the program is trying to call is does not exist.

The difference between the two is that one is an Error and the other is an Exception. With NoClassDefFoundError is an Error and it arises from the Java Virtual Machine having problems finding a class it expected to find. A program that was expected to work at compile-time can't run because of class files not being found, or is not the same as was produced or encountered at compile-time. This is a pretty critical error, as the program cannot be initiated by the JVM.

On the other hand, the ClassNotFoundException is an Exception, so it is somewhat expected, and is something that is recoverable. Using reflection is can be error-prone (as there is some expectations that things may not go as expected. There is no compile-time check to see that all the required classes exist, so any problems with finding the desired classes will appear at runtime.

ClassNotFoundException vs NoClassDefFoundError

NoClassDefFoundError

Thrown if the Java Virtual Machine or a ClassLoader instance tries to
load in the definition of a class (as part of a normal method call or
as part of creating a new instance using the new expression) and no
definition of the class could be found.

The searched-for class definition existed when the currently executing
class was compiled, but the definition can no longer be found.


ClassNotFoundException

Thrown when an application tries to load in a class through its string
name using: The forName method in class Class. The findSystemClass
method in class ClassLoader . The loadClass method in class
ClassLoader.


You have to understand that the JVM can't realize the definition of the class you deleted can't be found, as the class itself can't be found which automatically throw the ClassNotFoundException.

This exception happen at runtime so it does not matter if it compiled first or not, you deleted the file, therefore it can't be found and throw the exception.

Note that NoClassDefFoundError is not actually an exception, it is an Error derived from LinkageError while ClassNotFoundException derive directly from java.lang.Exception.

To resume, the NoClassDefFoundError globally simply mean that the JVM tried to access at runtime something that according to the compiled code should exists, but does not actually exist (or is not in the classpath).


Example to reproduce ClassNotFoundException

public class ClassNotFoundExceptionExample {

private static final String CLASS_TO_LOAD = "main.java.Utils";

public static void main(String[] args) {
try {
Class loadedClass = Class.forName(CLASS_TO_LOAD);
System.out.println("Class " + loadedClass + " found successfully!");
}
catch (ClassNotFoundException ex) {
System.err.println("A ClassNotFoundException was caught: " + ex.getMessage());
ex.printStackTrace();
}
}
}

Example to reproduce NoClassDefFoundError

Create a simple class Test

public class Test {
public Test() {
System.out.println("A new instance of the Test class was created!");
}
}

And a class NoClassDefFoundErrorExample

public class NoClassDefFoundErrorExample {
private static Test test = new Test();

public static void main(String[] args) {
System.out.println("The definition of Test was found!");
}
}

Now create a n executable .jar which execute the main method. You can specify it in the Manifest.txt file inside the .jar

Main-Class: NoClassDefFoundErrorExample

Now run the following commands

javac Test.java
javac NoClassDefFoundErrorExample.java
jar cfm NoClassDefFoundErrorExample.jar Manifest.txt NoClassDefFoundErrorExample.class
java -jar NoClassDefFoundErrorExample.jar

Notice the NoClassDefFoundError

Exception in thread "main" java.lang.NoClassDefFoundError: TestClass
at NoClassDefFoundErrorExample.(NoClassDefFoundErrorExample.java:2)
Caused by: java.lang.ClassNotFoundException: TestClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
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

What is difference between ClassNotFoundException and NoClassDefFoundError?

Class not found:

http://docs.oracle.com/javase/7/docs/api/java/lang/ClassNotFoundException.html

No Class Def:

http://docs.oracle.com/javase/7/docs/api/java/lang/NoClassDefFoundError.html

"Class not found" is pretty obvious: some reflection mechanism tried to refer to it's class by it's name, but the class wasn't around, so kablooey. That's pretty obvious. The name is wrong.

The sneaky one is the "No Class Def Found" error. That happens when you compile the code & everything is hunky-dorey, but at runtime, that class that was available at compile time just isn't there. Or, even more sneaky, it's there, but at the wrong version so it can't be used.

The first issue points to a configuration error. You've just got the wrong name.

The second issue points to a build error. You've either lost something from the build path, or you're running in a different JVM, or something whacky like that.

"Class Not Found" is usually pretty easy to fix, but "No Class Def" can have you pulling your hair out. If you're experiencing the latter, set about proving that the class mentioned is on the classpath, or in a jar on the classpath. Usually that effort shakes the problem out when I see it.

What is Difference between ClassNotFoundException vs NoClassDefFoundError vs Could not find or load main class XYZ?

NoClassDefFoundError - is a run-time error, thrown when the Definition of the class (which is .class file) cannot be found at run-time.

  • Imagine you've compiled class A.java alongside other files of your project; however, later on, you've removed compiled A.class file. So, compilation went fine, but actual bytecode of the class definition is absent, as A.class has been removed.

ClassNotFoundException - is a checked exception, thrown when your application tries to load the class through its String name, but the class isn't available on class-path.

  • An example can be Class.forName("com.mysql.jdbc.driver"); method call in your code, when, however, you don't have com.mysql.jdbc.driver available in your project.

Couldn't find or load main class XYZ - is an error, indicating, that the class you instruct JVM to run, doesn't contain the must have entry-point public static void main(String[] args) method, and reasons for this can be different, mainly one from this list:

  • you don't provide a correct Fully Qualified Name of your main class;
  • main method is not defined with the correct signature;
  • you messed up the packaging / you don't run the program with super.sub.grandchild.MainClass name;
  • you have .class postfix after your classname, which you should remove.

Why am I getting a NoClassDefFoundError in Java?

This is caused when there is a class file that your code depends on and it is present at compile time but not found at runtime. Look for differences in your build time and runtime classpaths.

How can I solve java.lang.NoClassDefFoundError?

After you compile your code, you end up with .class files for each class in your program. These binary files are the bytecode that Java interprets to execute your program. The NoClassDefFoundError indicates that the classloader (in this case java.net.URLClassLoader), which is responsible for dynamically loading classes, cannot find the .class file for the class that you're trying to use.

Your code wouldn't compile if the required classes weren't present (unless classes are loaded with reflection), so usually this exception means that your classpath doesn't include the required classes. Remember that the classloader (specifically java.net.URLClassLoader) will look for classes in package a.b.c in folder a/b/c/ in each entry in your classpath. NoClassDefFoundError can also indicate that you're missing a transitive dependency of a .jar file that you've compiled against and you're trying to use.

For example, if you had a class com.example.Foo, after compiling you would have a class file Foo.class. Say for example your working directory is .../project/. That class file must be placed in .../project/com/example, and you would set your classpath to .../project/.

Side note: I would recommend taking advantage of the amazing tooling that exists for Java and JVM languages. Modern IDEs like Eclipse and IntelliJ IDEA and build management tools like Maven or Gradle will help you not have to worry about classpaths (as much) and focus on the code! That said, this link explains how to set the classpath when you execute on the command line.

Capitalization and NoClassDefFoundError vs ClassNotFoundException

HFS+ (Mac Extended) is usually not case sensitive. Since Mac OS 10.3 Apple introduced HFSX which can be case sensitive (but is not the default). If you did not specify the option by the disk initialization then your volume is most likely case insensitive.

See: http://en.wikipedia.org/wiki/HFS_Plus



Related Topics



Leave a reply



Submit