Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Exceptional practices, Part 2

Use exception chaining to preserve debugging information

  • Print
  • Feedback

Page 3 of 3

public class ResourceLoadException extends ChainedException { 
  public ResourceLoadException(String message) { 
    super(message);
  }
  public ResourceLoadException(String message, Throwable cause) { 
    super(message, cause);
  }
}


And modifying loadResource() method to properly chain the exception is similarly simple; just provide the original exception to the appropriate constructor for ResourceLoadException:

public class ResourceLoader { 
  public loadResource(String resourceName) throws ResourceLoadException {
    Resource r;
    try {
      r = loadResourceFromDB(resourceName);
    }
    catch (SQLException e) {
      throw new ResourceLoadException("Unable to load resource " 
                                      + resourceName, e);
    }
  }
}


The printStackTrace implementation in ChainedException as shown above is fairly primitive; you could easily improve it by matching each stack trace's trailing lines and only printing the lines unique to the outer traces. That would make the stack trace more compact and easier to read.

If we apply the write sensible throws clauses technique outlined in Part 1 -- have methods throw exceptions at the same abstraction level as the method itself -- it is possible for exceptions to be wrapped several times as they propagate through the program. For example, if our application were a Web server, the IOException encountered in the course of loading an image might first get wrapped in a ResourceException and then, as it propagates up the call stack, the exception might get further wrapped in an InvalidReply exception. But since each outer exception still contains the inner exception, a developer looking at the log file could determine the problem's exact cause and how it was handled as it passes from layer to layer.

Exception chaining in the JDK

In JDK 1.2, a small number of exception classes incorporated some limited exception-chaining features, such as java.lang.ClassNotFoundException. However, none of these extended a common chained-exception base class; each class that supported chaining built the chaining features directly into its implementation.

JDK 1.4 has extended the Throwable class to provide all the features of the ChainedException base class shown here. If you are developing your application for JDK 1.4 or later, you can simply use the exception-chaining features provided by Throwable. If you are writing code that must run on JDK 1.2 or 1.3 but will eventually migrate to 1.4, you can use ChainedException now and then simply change your exception classes from extending ChainedException to extending Exception when you migrate.

Get in the habit of using exception chaining

Exception chaining is a useful technique for preserving important error recovery information while at the same time allowing methods to translate lower-level exceptions into higher-level ones as they propagate up the call stack. It will be built into the Throwable class as of JDK version 1.4. Fortunately for developers not yet developing on 1.4, which at the time of this writing is nearly everyone, you can build exception chaining into your programs now with the simple ChainedException class provided here, and easily migrate to using the built-in support when you move to JDK 1.4.

About the author

Brian Goetz is a software consultant who has been developing software professionally for more than 15 years. He is a principal consultant at Quiotix, a software development and consulting firm located in Los Altos, Calif.

Read more about Tools & Methods in JavaWorld's Tools & Methods section.

  • Print
  • Feedback

Resources