3/09/2007

NoClassDefFoundError Vs ClassNotFoundException

What..When...?
I always wonder, why Java is not intelligent enough to fix problems in the code when it knows something goes wrong; rather than throwing just exceptions? May be Gosling wants it that way, saving donuts for him!

Now read on...

A.java

1  public class A{
2
3  public static void main(String []s) throws classNotFoundException{
4    B obj = new B();
5     // class.forName("B).newInstance()
6   }
7
8  }

B.java

1 public class B{
2 }


javac A.java
java A

This would throw a NoClassDefFoundError. Comment out line 4 and uncomment line 5. Now it would throw ClassNotFoundException.

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.

  • Otherwise NoClassDefFoundError is thrown.

    The interesting fact is that, this behaves differently when your application runs in OC4j Oracle application server. i.e. your application would throw a NoClassDefFoundError to ClassNotFoundException.

    If you dont want to miss your donut, add two catch blocks in your code...I already missed one..:(

    try{
     
     
     
        }catch(ClassNotFoundexception e1){
        }catch(NoClassDefFoundError e2){
       }

    Added on 9/14/2012:
    Further I also see of there are issues with class initialization, there could be NoClassDefFoundError.

    Once there is an initialization failure, JVM marks the class as bad, and subsequent attempts to use or access the class result in NoClassDefFoundError 

    9 comments:

    Arun said...

    Good Post Dinu. Have a little thing more to add.

    Consider, you have two custom classloaders - CL1 and CL2. A class loaded by CL1 when tried to be accessed by CL2 will also throw a ClassNotFoundException.

    And consider you have Class1 loaded by both CL1 and CL2, they both are not compatible even through they are the same. There we give some job to ClassCastException.

    Thanks
    Arun
    www.arunma.com

    Arun said...

    I cant resist adding this too...

    NoClassDefFoundError is the result of the futile implicit load of the class (Class1). Meaning the system classloader is trying to load the class Class1 due to inherent call by Class2 (may be an inheritence or composition there).

    ClassNotFoundException comes up when there is an explicit load, using ClassLoader.loadClass, Class.forName etc.

    Either way, its our code error.

    Dinesh said...

    I hear you Arun.

    Yogesh said...

    I do not agree with you Dinu.
    This will not compile unless you compile B.java

    javac A.java
    A.java:18: cannot find symbol
    symbol : class B
    location: class testapp.A
    B obj = new B();
    ^

    The way can be

    Compile B first
    Then Compile A
    Remove B.class
    Run A

    Javin Paul said...

    In my opinion java.lang.NoClassDefFoundError comes when problematic class was present during Compile time and that's why program was successfully compile but not available during run time by any reason. NoClassDefFoundError is more easy to solve than ClassNotFoundException because here we know that Class was present during compile time

    Yogesh said...

    Well said Javin Paul.

    Kiran Kumar said...

    Thanks for article.
    Both errors throws at runtime. CNFE throws when there are two version of class files in diffrettn class loaders.NCDFE throws when there is no .class file found in the at runtime.
    6 ways to resolve javalangnoclassdeffounderro

    Raj said...

    http://purejavasecrets.blogspot.in/2012/03/difference-between-classnotfoundexcepti.html


    check my blog for correct and satisfied answer,donot forget to join if u like my blog.........

    Dinesh said...

    Further I also see of there are issues with class initialization, there could be NoClassDefFoundError.

    Once there is an initialization failure, JVM marks the class as bad, and subsequent attempts to use or access the class result in NoClassDefFoundError

    Tired of seeing that 500 Bad gateway error while deploying a Springboot application in AWS...?

    By default, Spring Boot applications will listen on port 8080. Elastic Beanstalk assumes that the application will listen on port 5000. Th...