Presents your JAVA E-NEWSLETTER for May 8, 2003 <-------------------------------------------> TAKE ADVANTAGE OF CHAINED EXCEPTIONS Chained exceptions were new to Java 1.4, but programmers have been using them for years, either coding their own or using one of the third-party implementations floating around. Now chained exceptions are part of the standard API. Chained exceptions are useful because they can provide a look back in time to the root cause, if any, of the current exception. Although you can get the root exception by calling the getCause method of the current exception (like in the code below), you wouldn't normally do so: Throwable t = e.getCause(); When you print an exception's stack trace, if it has a cause exception, the cause's stack trace will be printed; if the cause has a cause, its stack trace will be printed, and so on. Here's the stack trace of an exception that has a root exception, along with the code that printed the stack trace: public class ChainedTip { public static void main(String args[]) { try { foo(); } catch(TipException e) { e.printStackTrace(); } } public static void foo() throws TipException { try { FileInputStream in = new FileInputStream("not.there"); } catch (IOException e) { throw new TipException(e); } } } tips.TipException: java.io.FileNotFoundException: not there (The system cannot find the file specified) at tips.ChainedTip.foo(ChainedTip.java:21) at tips.ChainedTip.main(ChainedTip.java:9) Caused by: java.io.FileNotFoundException: not.there (The system cannot find the file specified) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.(FileInputStream.java:103) at java.io.FileInputStream.(FileInputStream.java:66) at tips.ChainedTip.foo(ChainedTip.java:18) ... 1 more The line that starts with "Caused by:" indicates the cause of the TipException. As you can see, there's plenty of information available for anyone who wants to read it. As a matter of fact, chained exceptions can lead to a bit of information overload. When an exception occurs in a deeply nested class (typical of classes executing inside containers), you can get stack traces that are pages long, but essentially contain only one error. Even with this drawback, chained exceptions are still worth using. The alternative is to lose the root exception, which can make diagnosing a problem much more difficult. To take advantage of chained exceptions when you are creating your own exceptions, code two constructors in addition to the ones you normally provide for your exception types. class TipException extends Exception { public TipException() {} public TipException(String msg) { super(msg); } public TipException(String msg, Throwable t) { super(msg, t); } public TipException(Throwable t) { super(t); } } The two constructors that accept Throwable objects are all you have to implement to provide exception chaining for your own exceptions. In these constructors, you pass the Throwable objects to the super classes constructor and let it do all of the work for you. Chained exceptions are a small change to the Java API, but have had a large, mostly positive, impact on Java applications. ----------------------------------------