BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Effective Java Exceptions

Effective Java Exceptions

Bookmarks

A new article by Barry Ruzek on BEA's dev2dev site discusses the use of exceptions in Java and proposes a way of thinking about exceptions to help guide when to use checked versus unchecked exceptions. It separates exceptional conditions into faults and contingencies and describes how to handle each.

Ruzek argues that those who say Java's checked exceptions are a failed experiment are wrong. The Java library designers failed to acknowledge the two basic causes for method failure, resulting in the overuse of checked exeptions. Ruzek posits that the two causes for method failure are:

  • Contingency - An expected condition demanding an alternative response from a method that can be expressed in terms of the method's intended purpose. The caller of the method expects these kinds of conditions and has a strategy for coping with them.
  • Fault - An unplanned condition that prevents a method from achieving its intended purpose that cannot be described without reference to the method's internal implementation.

In his example of a CheckingAccount class in a banking system, stop payment orders or overdrafts are contingencies, while the database being down or a network cable unplugged are faults. Based on this breakdown, contingencies should be handled with checked exceptions and faults with unchecked exceptions.

When processing faults, unchecked exceptions fits with the design of the JRE (ArithmeticException and ClassCastException are RuntimeException subclasses), and minimizes clutter because methods upstream of the fault do not all need to handle or explicitly pass the exception on. Furthermore, he suggests in most cases you can use RuntimeException itself, rather than a subclass. Most of the time you only need to pass on a message, as the exceptions are chained (from 1.4 on). Ruzek lists four goals for handling faults:

  • Minimize code clutter
  • Capture and preserve diagnostics
  • Alert the right person
  • Exit the activity gracefully

To handle faults, he recommends a fault barrier, which he describes here:

The goal here is to free the functional portions of your application from the responsibility of processing faults. Separation of concerns is generally a good thing, and a central facility responsible for dealing with faults will pay benefits down the road. In the fault barrier pattern, any application component can throw a fault exception, but only the component acting as the "fault barrier" catches them. Adopting this pattern eliminates much of the intricate code that developers insert locally to deal with faults. The fault barrier resides logically toward the top of the call stack where it stops the upward propagation of an exception before default action is triggered.

The fault barrier will log the information to the application log file and then close the operation in a controlled manner. For contingencies he recommends extending Exception to add value or information to the message passed back and not to bother with logging. He argues that since they are expected conditions, logging merely informs you that the application is working as designed. If a contingency represents a significant event, that should be logged before the exception is thrown.

Lastly, Ruzek points out that aspect oriented programming provides a excellent way to handle faults and contingencies, as they are cross-cutting concerns.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • Exception Checking

    by Jonathan Locke,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    A different approach to this whole issue might be to stop explicitly declaring exception throws in implementation and instead move checking to various scopes surrounding usage. There are a few difficulties in doing this, but they are not insurmountable and this approach would solve the whole "is it checked or not" problem entirely.

  • Un-Effective Java Exceptions

    by Nikolay Tsankov,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Using exceptions to deal with expected and possibly often occurring conditions, is not effective at all! By doing this, you are basically using exceptions to control flow, and there are far better mechanisms for that - conditions. Exceptions should be used in exceptional conditions only, not in expected conditions! I have personally witnessed an application go down with OutOfMemoryErrors because of using exceptions this way. "Effective Java" anyone?

  • Re: Un-Effective Java Exceptions

    by Jonathan Locke,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I agree with you completely, but getting rid of checked exceptions would also be a HUGE mistake. The problem is that what is an "exceptional condition" is DEPENDENT ON USE CONTEXT, not declaration! In one usage scope (application, package, class or method), IOException may be something you want to catch and branch on. In another scope, the very same exception may be something that represents total failure.

    Because of this glaring problem it is completely clear that (a) no classification based checking system (Java) will EVER be workable (as you're pointing out) nor will (b) the LACK of a checking system (.NET CLR).

    The only sane way to deal with this whole mess is to do exception checking based on scope based usage contracts. Special declarations may be necessary to deal with dynamic code such as in interface boundaries (where it cannot be determined apriori what exceptions might be thrown), but the basic idea is pretty straightforward. You declare how different USAGE scopes either check or don't check different classes of exceptions. The compiler can then warn you about the branchable exceptional conditions you WANT to be warned about without telling you about terminal exceptional conditions you DON'T WANT to be told about.

  • Updated link to the actual article

    by Mike Bria,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The link has changed since the initial posting. It is here now:

    www.oracle.com/technology/pub/articles/dev2arch...

  • Re: Updated link to the actual article

    by David Castaneda,

    Your message is awaiting moderation. Thank you for participating in the discussion.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT