These two are very common exception/error that Java programmers see in their day to day work so it will be really helpful to troubleshoot our programs if we could understand the differences between these two classes.
This is what sun's java docs says about these two classes:
java.lang.ClassNotFoundException is 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.
java.lang.NoClassDefFoundError is 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 what is the difference between these two classes?
First difference is java.lang.ClassNotFoundException is subclass of java.lang.Exception, whereas java.lang.NoClassDefFoundError is subclass of java.lang.LinkageError and which is subclass of java.lang.Error.
Now let's understand difference between these two with some test code.
First I create a java file ClassNotFoundExceptionTest.java for ClassNotFoundException testing.
class SomeClass{
public void someMethod(){
System.out.println("SomeClass.someMethod() called");
}
}
public class ClassNotFoundExceptionTest{
public static void main(String[] args) {
try{
Class.forName("SomeClass");
//Above statement will throw ClassNotFoundException if it could not find SomeClass.class file in classpath.
}catch(Exception exp){
exp.printStackTrace();
}
}
}
If we remove SomeClass.class file from classpath and execute ClassNotFoundExceptionTest.class then above program gives us java.lang.ClassNotFoundException like below:
java.lang.ClassNotFoundException: SomeClass
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.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:10)
Now l create another java file NoClassDefFoundErrorTest which test NoClassDefFoundError for us.
class SomeClass{
public void someMethod(){
System.out.println("SomeClass.someMethod() called");
}
}
public class NoClassDefFoundErrorTest{
public static void main(String[] args) {
SomeClass someClass = new SomeClass(); //Above statement will give NoClassDefFoundError if it could not find SomeClass.class file in classpath.
//someClass.someMethod();
}
}
If we remove SomeClass.class file from classpath and execute NoClassDefFoundErrorTest.class then above program gives us java.lang. NoClassDefFoundError like below:
Exception in thread "main" java.lang.NoClassDefFoundError: SomeClass
at NoClassDefFoundErrorTest.main(NoClassDefFoundErrorTest.java:12)
Caused by: java.lang.ClassNotFoundException: SomeClass
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.ClassLoader.loadClassInternal(Unknown Source)
... 1 more
So we can see if SomeClass.class is not found in the classpath then class loading Class.forName("SomeClass") throws ClassNotFoundException whereas SomeClass object creation new SomeClass() gives us NoClassDefFoundError but root cause in both cases is non availability of SomeClass.class in the classpath.
Java is case-sensitive language so when your classname is not correctly spelt like you use Class.forName("someClass") or Class.forName("Someclass") for SomeClass.class then also your program will throw ClassNotFoundException.







So when we write code to load a class by using a method like forName, we would be interested in handling the condition and therefore what is thrown here is a subclass of Exception. Whereas if the JVM is unable to locate a class whcih was available at the time of compilation, it considered as a system related error condition which may not normally be handled, and so it throws a subclass of Error.
Nice article.