What is difference between ClassNotFoundException and NoClassDefFoundError in java







Difference between ClassNotFoundException and NoClassDefFoundError in java







ClassNotFoundException
NoClassDefFoundError
1

NoClassDefFoundError is a Error in java. Error and its subclasses are regarded as unchecked exceptions in java.

2

Here is the hierarchy of java.lang.ClassNotFoundException -


-java.lang.Object
-java.lang.Throwable
 -java.lang.Exception
  -java.lang.ReflectiveOperationException
   -java.lang.ClassNotFoundException

Here is the hierarchy of java.lang.NoClassDefFoundError -


-java.lang.Object
-java.lang.Throwable
 -java.lang.Error
  -java.lang.LinkageError
   -java.lang.NoClassDefFoundError
3
ClassNotFoundException is thrown when JVM tries to class from classpath but it does not find that class.
NoClassDefFoundError is thrown when JVM tries to load class which >
  • was NOT available at runtime but
  • was available at compile time.
4
ClassNotFoundException is thrown whenever an java application tries to load a class by passing class name as String in following methods -
  1. forName(String className) method of java.lang.Class class.
  2. findSystemClass(String name) method of java.lang.ClassLoader class.
  3. loadClass(String name) method of java.lang.ClassLoader class.
These methods will never throw NoClassDefFoundError.

ExceptionInInitializerError has got nothing to do with ClassNotFoundException.
You must ensure that class does not throws java.lang.ExceptionInInitializerError because that is likely to be followed by NoClassDefFoundError.


Similarity between ClassNotFoundException and NoClassDefFoundError in java

ClassNotFoundException
NoClassDefFoundError
ClassNotFoundException is thrown when JVM tries to class from classpath but it unable to find that class.
Or, you can simply say class was unavailable in classpath at runtime.
NoClassDefFoundError is thrown when JVM tries to load class but no definition of class could be found.

Or, you can simply say class was unavailable in classpath at runtime.




Example/Programs/Scenarios where ClassNotFoundException may be thrown in java>

  1. Loading classes via Reflection in java > ClassNotFoundException is thrown whenever an application tries to load a class by passing class name as String in forName(String className) method of Class class.
Example -
package ClassNotFoundExceptionExamplePkg;
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class ClassNotFoundExceptionExample {
public static void main(String... a) {
     System.out.println("initialize 'ReflectionClass' at runtime");
     // initialize 'ReflectionClass' at runtime
     Class cls = null;
     try {
          cls = Class.forName("ClassNotFoundExceptionExamplePkg.ReflectionClass");
     } catch (ClassNotFoundException e) {
          e.printStackTrace();
     }
}
}
/*OUTPUT
initialize 'ReflectionClass' at runtime
java.lang.ClassNotFoundException: ReflectionClass
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 ClassNotFoundExceptionExamplePkg.ClassNotFoundExceptionExample.main(ClassNotFoundExceptionExample.java:12)
*/

Solution - Make class available in package ClassNotFoundExceptionExamplePkg and call forName(String className) method of java.lang.Class class.

Example -
package ClassNotFoundExceptionExamplePkg;
class ReflectionClass {
static{
     System.out.println("ReflectionClass has been initialized");
}
}
/**
* Copyright (c), AnkitMittal JavaMadeSoEasy.com
* Main class
*/
public class ClassNotFoundExceptionAvoidExample {
public static void main(String... a) {
     System.out.println("initialize 'ReflectionClass' at runtime");
     // initialize 'ReflectionClass' at runtime
     Class cls = null;
     try {
          cls = Class.forName("ClassNotFoundExceptionExamplePkg.ReflectionClass");
     } catch (ClassNotFoundException e) {
          e.printStackTrace();
     }
}
}
/*OUTPUT
initialize 'ReflectionClass' at runtime
ReflectionClass has been initialized
*/



  1. ClassNotFoundException can be thrown when java application tries to load/initialize oracle.jdbc.driver.OracleDriver class by passing class name as String in Class.forName("oracle.jdbc.driver.OracleDriver") method of Class class but OracleDriver class is not present in classpath.
Example -
package ClassNotFoundExceptionExamplePkg2;
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class MyJdbcConnectionSetup {
public static void main(String... arg) {
     System.out.println("register Oracle driver class, i.e. initialize OracleDriver");
     try {
          // register Oracle driver class, i.e. initialize OracleDriver
          Class.forName("oracle.jdbc.driver.OracleDriver");
          System.out.println("Oracle driver class registered, i.e. initialized OracleDriver");
     } catch (ClassNotFoundException e) {
          e.printStackTrace();
     }
}
}
/*OUTPUT
register Oracle driver class, i.e. initialize OracleDriver
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
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 ClassNotFoundExceptionExamplePkg2.MyJdbcConnectionSetup.main(MyJdbcConnectionSetup.java:8)
*/

Solution - Make OracleDriver class available in classpath. Read how to  configure java build path - registering driver


Example -
package ClassNotFoundExceptionExamplePkg2;
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class MyJdbcConnectionSetup {
public static void main(String... arg) {
     System.out.println("register Oracle driver class, i.e. initialize OracleDriver");
     try {
          // register Oracle driver class, i.e. initialize OracleDriver
          Class.forName("oracle.jdbc.driver.OracleDriver");
          System.out.println("Oracle driver class registered, i.e. initialized OracleDriver");
     } catch (ClassNotFoundException e) {
          e.printStackTrace();
     }
}
}
/*OUTPUT
register Oracle driver class, i.e. initialize OracleDriver
Oracle driver class registered, i.e. initialized OracleDriver
*/




Example/Programs/Scenarios where NoClassDefFoundError may be thrown in java>


  1. We will create very simple program which will throw NoClassDefFoundError .

NoClassDefFoundError is thrown when JVM tries to load class but no definition of class could be found.

First let’s write java class >
public class NoClassDefFoundErrorExample {
public static void main(String[] args) {
        new A(); // It can throw java.lang.NoClassDefFoundError
}
}
class A {
}

Let’s say above code in file =  E:\workspace\NoClassDefFoundErrorExample.java

Go to CMD and type below commands >

C:\Users\ankitmittal01>e:

E:\>cd E:\workspace

E:\workspace>javac NoClassDefFoundErrorExample.java

E:\workspace>

As soon as javac NoClassDefFoundErrorExample.java is called two .class files are formed.

Directory of .class files = E:\workspace\NoClassDefFoundErrorExample.class and
E:\workspace\A.class


Now, when above program can throw  NoClassDefFoundError?

Now, delete E:\workspace\A.class

Let’s say you have deleted A.class. Now, let's execute the program again >
E:\workspace>java NoClassDefFoundErrorExample
Exception in thread "main" java.lang.NoClassDefFoundError: : A
       at NoClassDefFoundErrorExample.main(NoClassDefFoundErrorExample.java:3)
Caused by: java.lang.ClassNotFoundException: A
       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)
       ... 1 more

E:\workspace>
As we see NoClassDefFoundError was thrown when JVM tries to load A.class which >
    • was NOT available at runtime but
    • was available at compile time.




  1. If any RuntimeException occurs in >
then NoClassDefFoundError may be thrown.

We will create another simple program to understand how RuntimeException occured in static block of class can throw NoClassDefFoundError.

First let’s write java class >
package noClassDefFoundErrorPkg;

public class NoClassDefFoundErrorExample {
public static void main(String[] args) {
    try {
        new A(); // It will throw java.lang.ExceptionInInitializerError
    } catch (Error error) {
        error.printStackTrace();
    }
   
    System.out.println("\n--------------\n");
   
    try {
        new A(); // It will throw java.lang.NoClassDefFoundError
    } catch (Error error) {
        error.printStackTrace();
    }
}
}
class A {
static {
    System.out.println("In static block of class A");
    System.out.println(1 / 0); // It will throw java.lang.ArithmeticException
}
/*
* Constructor of class A will never get executed
*/
A() {
    System.out.println("In constructor of class A");
}
}

Output of above program >
In static block of class A
java.lang.ExceptionInInitializerError
at noClassDefFoundErrorPkg.NoClassDefFoundErrorExample.main(NoClassDefFoundErrorExample.java:6)
Caused by: java.lang.ArithmeticException: / by zero
at noClassDefFoundErrorPkg.A.<clinit>(NoClassDefFoundErrorExample.java:27)
... 1 more
--------------
java.lang.NoClassDefFoundError: Could not initialize class noClassDefFoundErrorPkg.A
at noClassDefFoundErrorPkg.NoClassDefFoundErrorExample.main(NoClassDefFoundErrorExample.java:14)

In the above program, first new A() at line 6 throwed ExceptionInInitializerError because ArithmeticException occurred in initializing the class (i.e. in static block of class) then,
new A() at line 14 throwed NoClassDefFoundError because class initialization has already thrown error.

You must read ArithmeticException  is an unchecked exception and it is propagated automatically in java.



  1. We will create another program which uses commons-lang.jar and will throw NoClassDefFoundError .

NoClassDefFoundError is thrown when JVM tries to load class but no definition of class could be found.

First let’s write java class >
import org.apache.commons.lang.StringUtils;
public class NoClassDefFoundErrorExample {
public static void main(String... arg) {
    System.out.println(StringUtils.class + " loaded");
    System.out.println(StringUtils.isNotEmpty("java")); //true
}
}

Let’s say above code in file =  E:\workspace\NoClassDefFoundErrorExample.java

Go to CMD and type below commands >

Set required jar (commons-lang.jar) in classpath
and then execute javac command.
C:\Users\ankitmittal01>e:

E:\>cd E:\workspace

E:\workspace>set CLASSPATH=.;E:\java jars\commons\commons-lang.jar

E:\workspace>javac NoClassDefFoundErrorExample.java

E:\workspace>

As soon as javac NoClassDefFoundErrorExample.java is called .class file is formed.

Directory of .class file = E:\workspace\NoClassDefFoundErrorExample.class

Now, when above program can throw  NoClassDefFoundError?

Now, either unset the the classpath by using command >
set CLASSPATH=
Or,
Delete or move E:\java jars\commons\commons-lang.jar

Let’s say you have unset the classpath. Now, let's execute the program again >
E:\workspace>set CLASSPATH=

E:\workspace>java NoClassDefFoundErrorExample
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils
       at NoClassDefFoundErrorExample.main(NoClassDefFoundErrorExample.java:5)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils
       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)
       ... 1 more

E:\workspace>
As we see NoClassDefFoundError was thrown when JVM tries to load org.apache.commons.lang.StringUtils class which >
    • was NOT available at runtime but
    • was available at compile time.


Note : Jar used in above program = commons-lang.jar

Must read for you :

No comments:

Post a Comment