In this tutorial we’ll discuss about exception chaining, which may be new term to few java EE developers.
Note: If at any time, you feel no need for such tutorial, execute the two programs in the post and learn what exception chaining is all about.
The most important thing to remember about Exception chaining is that we need to use the constructor of the exception classes which accepts a parameter of type Throwable so that it can keep a reference to the exception which was the cause of this exception.
Definition of Exception Chaining:
The definition of chained exceptions is that when the occurrence of one exception raises another exception then the stack trace of second exception should also include the root exception in the application logs.
Few points to remember about Chained Exceptions are:
1) Java does magic in order to support Exception Chaining but it is also the responsibility of the developer to have proper exception chaining mechanism in place in any Java based application. The application needs to be coded so as to support exception chaining.
2) If the developer doesn't take any action to have chained exception in his program, the root exceptions are lost. No exception chaining code, no chained exceptions seen.
3) Chained exceptions are different from the stack trace that we see when an exception occurs which prints the method names which we were invoked before the exception was thrown (in other words, the method stack trace)
4) Exception Chaining is internally supported by Java by storing a reference to the root exception has a member field cause which was added in JDK 1.4 and looks like:
private Throwable cause = this; (inside Throwable.java class)
5) The methods which are provided by Java in order to only support exception chaining are
Throwable getCause()
Throwable initCause(Throwable)
Throwable(String, Throwable)
Throwable(Throwable)
Throwable printStackTrace();
The basic and important point to keep in mind about chained exception is that we need to write a custom exception class which can accept an argument of type Throwable in is constructor and can invoke the super class's constructor with the parameters passed to its constructor. This will become more clear with two examples:
Without any Exception Chaining mechanism in place:
package com.vaani.exception.notchained
class MyException extends Exception { //Custom Exception class
public MyException (String msg) {
super(msg);
}
}
public class Test {
static int a[] = {1,2,3};
public static void main(String[] args) {
try {
System.out.println(a[4]); //Deliberate ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException ae) {
try {
throw new MyException("Exception Occured"); //throw custom exception
} catch (MyException me) {
me.printStackTrace();
}
}
}
}
Output:
com.vaani.exception.notchained.MyException: Exception Occured
at com.example.Test.main(Test.java:20)
With Exception Chaining mechanism in place:
package com.vaani.exception.chained;
class MyException extends Exception { //Custom Exception class
public MyException (String msg, Throwable ex) {
super(msg, ex);
}
}
public class Test {
static int a[] = {1,2,3};
public static void main(String[] args) {
try {
System.out.println(a[4]); //Deliberate ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException ae) {
try {
throw new MyException("Exception Occured",ae); //throw custom exception
} catch (MyException me) {
me.printStackTrace();
}
}
}
}
Output:
com.vaani.exception.chained.MyException: Exception Occured
at com.example.Test.main(Test.java:19)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 4
at com.example.Test.main(Test.java:16)
Please note that the use of custom exception in above examples is for demonstration only. It could be any JDK exception class like IllegalArgumentException, ClassNotFoundException or IllegalStateException.