The subject of this RT is the issue of checked vs. unchecked exceptions and the horrible things the abuse of checked exceptions does to our code base.

I won't retiterate what others, with much more experience than me, have written on the subject. You can find the opinions of Bruce Eckel, Rod Johnson (of Spring fame), E.R. Harold and Anders Hejlsberg (father of C#) here [1], here [2], here [3] and here [4].

You might also read Item #41 in Joshua Bloch's "Effective Java", if you own the book, for a less radical position than Eckel's one, or James Gosling's interview here [5] to hear a somewhat more conservative stand.

Anyway, enough with appeal to authority. Let's see what the problems with checked exceptions in Cocoon's sources are:

- rethrowing exceptions wrapped around unrelated exceptions to conform to an interface signature.

- swallowing exceptions without notice (besides an occasional getLogger().debug() call).

- mile-long stack traces due to exceptions wrapping exceptiions wrapping exceptions ... ad nauseam.

- lots of useless catch blocks littering code and harming readability.

Admittedly, many checked exceptions are thrown by Java core libraries or Avalon. The latter is a big offender in this respect: all exceptions extend CascadingException instead of CascadingRuntimeException.

The problem is that I see the same error is being done for Cocoon 2.2. The new "kernel" uses checked exceptions exclusively, for instance.

I hope I'm not offending anyone with this, but maybe the tendency to always use checked exceptions is due to the (misguided) belief that compile-time checking is a good substitute for an ample test coverage. Well, it is not.

So, I'd like to make a proposal:

- use unchecked exceptions *by default* unless there's a good reason otherwise, not just because that's the way it's always been done.

- wrap exceptions thrown by 3rd party packages (e.g. org.xml.sax.SAXException) with Cocoon-specific, unchecked exceptions (basicallly, abstain from throwing checked exceptions belonging to a package different from the method's one, as this creates an unnecessary dependence).

- write tests to verify that methods don't throw exceptions for valid inputs and that they throw appropriate exceptions (e.g. InvalidArgumentException) for invalid ones.

- document with a throws clause any unchecked exception that you explicitly throw in a method, even if it's not required to do so. Document it in the javadoc comment too.

- for the next release (2.1.5), reparent all exceptions now extending CascadingException, to extend CascadingRuntimeException instead and remove all the code that does nothing more than rethrow them.

- do the same for the Source package.

Now just give me time to don my asbesto suite before firing ;-)

Ugo

[1] http://www.mindview.net/Etc/Discussions/CheckedExceptions
[2] http://www.artima.com/intv/jdom3.html
[3] http://www.artima.com/intv/handcuffs.html
[4] http://www.theserverside.com/articles/article.tss?l=RodJohnsonInterview (read inside the PDF of the sample chapter)
[5] http://www.artima.com/intv/solid.html


Reply via email to