First, let's see the possible exceptions or errors that could raise during a class loading process :
java.lang.Exception
+->java.lang.ClassNotFoundException
java.lang.LinkageError
+->java.lang.NoClassDefFoundError
+->java.lang.ClassCircularityError
+->java.lang.ClassFormatError
+->java.lang.VerifyError
+->java.lang.IncompatibleClassChangeError
| +->java.lang.InstantiationError
| +->java.lang.AbstractMethodError
+->java.lang.ExceptionInInitializerError
java.lang.VirtualMachineError
+->java.lang.OutOfMemoryError
The most common exception or errors would be: ClassNotFoundException and NoClassDefFoundError. Both means the same information - not able to load a given class (or interface) from the known classpath. Then, why two types ?
Exception is something which a programmer should anticipate during his program execution. Which means - the code can fail, but should be able to recover from that using exception handlers. How can it happen ? The answer is - when using Java API (Application Programming Interface) to find and load the class. Java API provides java.lang.Class.forName(), using which a programmer can request the ClassLoader to find and load (if not already done) a class by providing it's String name.
From the API specification, Class.forName() can throw any one of these when it is not able to find and load the requested class: ClassNotFoundException and LinkageError (any subclass of it).
Class c = null;
try {
c = Class.forName("AVeryNewClassName");
info.log("Using custom settings...");
} catch(ClassNotFoundException handle) {
// handle the exception
info.log("Using default settings...");
c = DEFAULT_CLASS;
}
On the other hand a programmer should not anticipate an Error in his program execution. Though some errors are catchable, it is not advisable. The reason being, the Java VM has identified it as an Error and it's internal state may get affected if the program continues to run with that error. When the JVM is very sure about the Error, it gives out the message and shuts down itself. OutOfMemoryError is a good example. When JVM decides that there is no space for any new object, it gives out the message and comes down.
The following code uses a class which was available during the compilation of this class, but not available during runtime. This throws NoClassDefFoundError. Here there is no API being used to construct the class or instance of it. This line (new operator) requires the class to be loaded and initialized to create an instance of it. Thereby this statement has to throw an Error, which should not be caught. NoClassDefFoundError is a subclass of LinkageError, meaning that this error has occurred during linking a class.
CompileTimeOnlyClass c = new CompileTimeOnlyClass();
or
CompileTimeOnlyClass.invokePublicStaticMethod();Internally, JVM uses ClassLoaders to search a class and recieves the ClassNotFoundException. This will get converted into NoClassDefFoundError, if the class loading operation is initiated by the JVM. You would get the same error if you run the following command:
% java NotYetCompiledClass
Exception in thread "main" java.lang.NoClassDefFoundError: NotYetCompiledClass
No comments:
Post a Comment