java.lang.ClassNotFoundException and java.lang.NoClassDefFoundError
java.lang.ClassNotFoundException vs java.lang.NoClassDefFoundError
JAVA throws for fatal issues Error and recoverable issues as Exception. While it comes to class loading exception/error, it is really a myth for developer, who are novice to classloader and its behaviour. Aforementioned classes get used to intimate the issue based on the nature of the class loading.
In general, these issues raises for the same reason of non-existing class in run time. The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found in the time of Application getting executed.
ClassLoader
ClassLoader used to load the bytecodes and convert the same to runnable format based on the platform. In classLoader, findClass() and loadClass() are the methods which helps us to create the instance of objects. loadClass() method get called by JVM, to load class, where new class reference found in the application. If already the definition of class found then Class object will be returned. If given class reference not loaded already then findClass() get called and implementation of this method responsible to find the binary for the class. Once binary found then findClass() method which calls defineClass() to return Class object.
ClassNotFoundException
This class extends Exception. After throwing this exception also ClassLoader can able to proceed and will not break the application.
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. This is final method and get called by JVM..
- The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found. Default implementation of findClass() also throws ClassNotFoundException.
The above mentioned APIs are pretty safe and mostly used to make lazy loading of classes. Even specified class not found also, no issues application implementor can decide to take alternate approach of business.
For instance, We have Web container application, and ClassLoader is written by us to load classes(eg: Servlet) which are comes part of web application. While doing web application deployment, our ClassLoader has to load the classes referred in web.xml as Servlet. If any one of the class not found then it has to throw just an exception, and rollback deployment. No need of webcontainer stop, it can continue to doing its business.
ClassNotFoundException.java
public class ClassNotFoundExceptionTest {
public static void main(String[] args) {
Class.forName(""); // empty space also throws ClassNotFoundException
ClassLoader.getSystemClassLoader().loadClass("NonExistingClass$subclass"); // non-existing class in classpath
}}
$javac *.java
$java ClassNotFoundExceptionTest
Exception in thread "main" java.lang.ClassNotFoundException:
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:4)
Comment Class.forName(""); line and compile and run
Exception in thread "main" java.lang.ClassNotFoundException: NonExistingClass$subclass
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:303)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:5)
NoClassDefFoundError
This error occurs whenever JVM could not able to progress application due to non-existing class reference found in object creation.
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.
Create following classes in a same folder and compile both java files.
MainClass.java
public class MainClass {
public static void main(String[] args) {
Object a= new NonExistingClass();
}
}
NonExistingClass.java
public class NonExistingClass {}
$javac *.java
$java MainClass
No error will be thrown
$ rm NonExistingClass.class
$ java MainClass
Exception in thread "main" java.lang.NoClassDefFoundError: MainClass
Caused by: java.lang.ClassNotFoundException: MainClass
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)
Could not find the main class: MainClass. Program will exit.
Evenmore, we can see NoClassDefFoundError in JVM startup, by refering non-existing class
$ java NonExistingClass
Exception in thread "main" java.lang.NoClassDefFoundError: NonExistingClass
Caused by: java.lang.ClassNotFoundException: NonExistingClass
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)
Could not find the main class: NonExistingClass. Program will exit.
No comments:
Post a Comment