ClassNotFoundException vs NoClassDefFoundError


As per Java API Specifications .
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.

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.


Lets try to understand with an example
ClassNotFoundException Example
  
public class ClassNotFoundExceptionDemo {

 public static void main(String[] args) {
  try {
   Class.forName("noClass");
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
 }
}

Here the class ClassNotFoundExceptionDemo trying to instansiate the class ("noClass") using Class.forName method, but the noClass class does't exist.
Here's what happens if you run this program:
java.lang.ClassNotFoundException: noClass
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at ClassNotFoundExceptionDemo.main(ClassNotFoundExceptionDemo.java:6)

More general, ClassNotFoundException is a runtime exception when you try to use a class that doesn't exist.

NoClassDefFoundError example
  
public class NoClassDeffFoundErrorDemo {
 public static void main(String[] args) {
 Test test = new Test();
}
}

class Test{
 
}

save this as NoClassDeffFoundErrorDemo.java somewhere

The code simply tries to instantiate a new "Test" class , other than that, it doesn't have any bugs, and it doesn't do anything.

Compile the code with javac NoClassDeffFoundErrorDemo.java and run the class, and it should run fine without errors.

Then delete the "Test.class" file  to simulate the missing or corrupted class. Here's what happens:

java NoClassDeffFoundErrorDemo
Exception in thread "main" java.lang.NoClassDefFoundError: NoClassDeffFoundError
Demo
Caused by: java.lang.ClassNotFoundException: NoClassDeffFoundErrorDemo
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: NoClassDeffFoundErrorDemo.  Program will exit.

In short, a NoClassDefFoundError is usually thrown on new() statements or method invocations that load a previously absent class (as opposed to the string-based loading of classes for ClassNotFoundException), when the classloader is unable to find or load the class definition(s).


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.

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...