Friday, December 6, 2013

Difference Between ClassNotFoundException and NoClassDefFoundError


ClassNotFoundException (java.lang.ClassNotFoundException): 
ClassNotFoundException is a checked Exception derived directly from java.lang.Exception class.
public class ClassNotFoundException extends Exception
}
Note:  java.lang.ClassNotFoundException is an Exception Which is checked. So we need to handle the exception by using either try-catch or finally block.

A ClassNotFoundException is thrown when the ClassLoader could not find the required class in the CLASSPATH.

When an application tries to load in a class through its string name using:
  1. The Class.forName() method
  2. The  ClassLoader.loadClass() method
  3. The ClassLoader.findSystemClass() method
but no definition for the class with the specified name could be found.

Some of the possible reasons to get this exception is
  1. The class is missing from the classpath.
  2. The class in question is trying to be loaded from another class which was loaded by different classloader.
    This is an Exception, so can be handled using Exception handling in Java.
    Example:
    ClassNotFoundExceptionDemo.java
    public class ClassNotFoundExceptionDemo {
    public static void main(String[] args) throws Exception{
    Class myClass = Class.forName("Test");
    }
    }
    [ranga@ranga java]$ javac ClassNotFoundExceptionDemo.java
    [ranga@ranga java]$ java ClassNotFoundExceptionDemo
    Exception in thread "main" java.lang.ClassNotFoundException: Test
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at ClassNotFoundExceptionDemo.main(ClassNotFoundExceptionDemo.java:3)
    [ranga@ranga java]$

    To avoid ClassNofFoundException exception, you need to take care of following things.
    1. Make sure that Class is available in the logical class path of the class loader associated with the class.
    2. Make sure that Class Loader API is used properly .ie whether a wrong class Loader is engaged in Class.forName().
    3. Make sure that dependent class of the class being loaded is visible to the class  loader.
    NoClassDefFoundError (java.lang.NoClassDefFoundError): 

    NoClassDefFoundError is an Error derived from LinkageError which extends java.lang.Error class.
    public class NoClassDefFoundError extends LinkageError {
    }  
    Note:  java.lang.NoClassDefFoundError is an Error Which is unchecked. So no need of Error  of try-catch or finally block.

    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. NoClassDefFoundError can be thrown during linking or loading of class file.

    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.
    This is an Error, means thrown by JVM so can't be recovered and program crashed.
    Some of the possible reasons to get this error is
    1. If a dependent class cannot be located and loaded means the directly referenced class might have been located and loaded, but the dependent class is not available or cannot be loaded.
    2. You are using some library, like hibernate or spring, or Apache commons, and forgot to add this jar to your CLASSPATH.
    3. Bad format of the class
    4. The version number of a class not matching.
    Example :
    NoClassDefFoundErrorDemo.java

    public class NoClassDefFoundErrorDemo {
        public static void main(String ranga[]) throws Exception {
           Test test = new Test();
        }
    }
    class Test {
      Test() {
        System.out.println("Test()");
      }
    }

    Now compile the NoClassDefFoundErrorDemo.java class.

    [ranga@ranga java]$ javac NoClassDefFoundErrorDemo.java

    [ranga@ranga java]$ ls
    NoClassDefFoundErrorDemo.class  NoClassDefFoundErrorDemo.java  Test.class

    After compilation you can see the two .class files(NoClassDefFoundErrorDemo.class and Test.class). Now delete Test.class file (I did in Linux Terminal).

    [ranga@ranga java]$ rm -r Test.class

    Finally run the NoClassDefFoundErrorDemo class file.
    [ranga@ranga java]$ java NoClassDefFoundErrorDemo
    Exception in thread "main" java.lang.NoClassDefFoundError: Test
        at NoClassDefFoundErrorDemo.main(NoClassDefFoundErrorDemo.java:3)
    Caused by: java.lang.ClassNotFoundException: Test
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        ... 1 more
    [ranga@ranga java]$

    Similarities:
    1) Both NoClassDefFoundError and ClassNotFoundException are related to unavailability of a class at run-time.
    2) Both ClassNotFoundException and NoClassDefFoundError are related to java classpath.

     
    About ClassLoader:
    A class loader is a Java object responsible for loading classes. Basically a class loader attempts to locate or generate data that constitutes a definition for the class. One of the key points to understand is that Java class loaders by default use a delegation model to search for classes. Each instance of ClassLoader has an associated parent class loader. So let’s say that your application class loader needs to load class A. The first thing that it will attempt to do is to delegate the search for Class A to its parent class loader before attempting to find the Class A itself. You can end up with a large class loader chain with many parent class loaders up to the JVM system classpath bootstrap class loader.

    0 comments: