Fixing Checked Exceptions

13 views
Skip to first unread message

kiwisincebirth

unread,
Jun 23, 2007, 2:20:29 AM6/23/07
to The Java Posse
Fixing Checked Exceptions (An Alternative to removing them)

My opinion based on background of 5 years mainly server side
development.

The debate about (Non)Checked Exceptions is as old as their
introduction in Java itself, I think it should be left up to the
individual to use them appropriately, they both have there merits.

They question I want to address is "What is broken about current
checked exceptions, and how do we fix it?"

In my experience checked exceptions are ideal where there is a
possibility of some recovery of the situation, they force the
developer to deal with that possibility. Runtime exceptions are for
unexpected situations, which should not have arisen, where you cannot
specifically deal with the situation, and want to implement a general-
purpose handler.

The Biggest Issue

In my experience the biggest issue arises with the handling of
multiple checked exceptions and the misuse (simplification) of the
catch block. Eg.

try {
Object obj = Class.forName("myClass").newInstance();
// do something with the object
} catch (Exception e) {
// handle the ClassNotFound, IllegalAccess, and Instantiation,
Exceptions
}

This sort of code is commonplace in a lot of code that I look at. This
issue is that any RuntimeException is also caught and hidden from the
system. This results in undetected issues, which may eventually cause
issues in the system.

The alternative to the above is to have complex error handling
generally involving catching the individual exceptions. The developer
ends up writing as much error handling code, as actual code. This
quickly leads to complex and hard to maintain code.

My proposition is to change the Exception hierarchy from this

Throwable
-> Error
-> Exception
----> RuntimeException

TO THIS:

Throwable
-> Error
-> Catchable
----> Exception
----> RuntimeException

Note: the new Catchable inserted above Exception, and RuntimeException
moved as a sub-class of Catchable.

Benefit

Catch (Exception e) can now be used properly to catch all checked
exceptions, without affecting runtime exceptions. This would be a
paradigm shift in the way exception handling code would be written. It
would simplify exception handling code, which is one of the
criticism's of checked exceptions

Implications

Code that catches Exception would no longer catch a RuntimeException.
This is a good and bad thing, it will actually cause code to fail, as
the RuntimeException's would now be thrown, but actually the
RuntimeException has always be thrown, just previously it was being
lost in catch block.

catch (Catchable e) would replace the use of catch (Exception e) where
we want to actually want to catch the RuntimeException's. However code
which is looking to specifically handle RuntimeException's should
probably catch RuntimeException specifically anyway.

I would suspect that the amount of code that would legitimately need
change to catch (Catchable e) would be far less that the amount of
code that would remain un-changed.

Code backwards compatibility, could be maintained by introducing the
Catchable class, but not re-inheriting the RuntimeException class.

Ultimately these issues would be resolved, but there would be a cost
to migrate to a new Java, but no different to some of the other
changes being suggested for Java

Mark.

Mark Derricutt

unread,
Jun 23, 2007, 6:51:33 AM6/23/07
to java...@googlegroups.com
Unrelated to the idea mentioned here (which I like) I came up with another interesting idea as I'm currently going through some inherited code and changing an Exception to a RuntimeException (5 layers of calls each catching, logging, then throwing a generic PersistenceException - seems a tad overkill).

Anyway, I was thinking about Domain Specific Exceptions and reworking some of the above PersistenceException throws to things like DuplicateUserException, DuplicateCompanyException yadda yadda.  I was thinking it might be better to be a -bit- generic with DuplicateException but part of me didn't like the lack of type specific information.

The idea I had was generic exceptions - sadly with the way type erasure works with generics currently this idea doesn't work, but if it did - you could write things like:

try {
  // blah blah blah
} catch (DuplicateException<User> e) {
  // ewps
} catch (DuplicateException<Company> e) {
  // arg
}

Not sure how useful something like this may be - but could be quite flexible.

I'd be interested in knowing how you all design your exception model (if at all) - generic names, different exceptions for every part of the domain, extending each exception from a generic MyApplicationException or directly from Exception/RuntimeException?

Mark

Alexey Zinger

unread,
Jun 23, 2007, 1:11:42 PM6/23/07
to java...@googlegroups.com
I'm not sure what that gives us over current ability to do one of the two:

1. Do a big "if-else" decision tree in one catch based on the contents of your generic exception.  Mildly ugly, but not so ugly that I would change the language.

catch(DuplicateException ex)
{
  Object src = ex.getSource();
  if(src instanceof Company)
    ...
  else if(src instanceof User)
    ...
  else
    ...
}

2. Have your generic exception store an additional "type" property that can be put into a "switch" statement.  This requires a bit more work on the thrower of the exception and does not enforce casting safety if that's what you're doing down the line.  But it is faster than checking types I think.

catch(DuplicateException ex)
{
  switch(ex.getSourceType)
  {
    case DuplicateException.TYPE_COMPANY:
    ...
    break;

    case DuplicateException.TYPE_USER:
    ...
    break;

    default:
    ...
  }
}

3. Build your exception hierarchy getting away from the one-exception-fits-all approach.  I think this is what fits the language's intent best.

catch(CompanyDuplicateException ex)
{
  ...
}
catch(UserDuplicateException ex)
{
  ...
}
catch(DuplicateException ex)
{
  ...
}

Mark Derricutt <ma...@talios.com> wrote:

Need a vacation? Get great deals to amazing places on Yahoo! Travel.

Reinier Zwitserloot

unread,
Jun 23, 2007, 3:27:11 PM6/23/07
to The Java Posse
Making RuntimeException no longer extend Exception breaks code in
subtle, not easy to detect ways.

It's not, by any means, a "Whoa! That would completely fix
everything!" solution, it's a debatable, minor improvement.

A couple of Whoa! solutions that break old code in obvious, easy to
detect ways is being turned down because of the backwards
compatibility thing.

Don't shoot the messenger, but chances that this idea ever gets
implemented: Somewhere between hell freezing over and winning the
lottery without buying a ticket.

Introducing a CheckedException exception that becomes a parent of all
the CheckedExceptions that java(x).* offers is a less clean but
similar solution that has slightly more chance, but I'm entirely with
the if/then camp here. If this simple little maneuvre is all that's
going to be done, then might as well leave it and use an if ( e
instanceof RuntimeException ) type of solution.

No; if we're going to talk about 'fixing' exceptions, find something
which is 100% backwards compatible on both binary and source levels.
Incidentally, "ignores SomeException, SomeOtherException" is 100%
backwards compatible, binary and source level.

kiwisincebirth

unread,
Jun 23, 2007, 8:34:59 PM6/23/07
to The Java Posse
> Somewhere between hell freezing over and winning the
> lottery without buying a ticket
Agree with you on that one, thought I would put it out there.

> then might as well leave it and use an if ( e
> instanceof RuntimeException ) type of solution.

This is actually my current solution, however not everyone is as
competent as members of this forum. Exception handling code is one of
the anti-patterns of the Java world, I dont agree getting rid of
checked exceptions is the right answer. I think we need simpler way of
handling exceptions, which leave no room for inexperienced developers
to get wrong.

Reinier Zwitserloot

unread,
Jun 23, 2007, 9:41:39 PM6/23/07
to The Java Posse
> This is actually my current solution, however not everyone is as
> competent as members of this forum. Exception handling code is one of
> the anti-patterns of the Java world, I dont agree getting rid of
> checked exceptions is the right answer. I think we need simpler way of
> handling exceptions, which leave no room for inexperienced developers
> to get wrong.
>

Unfortunately, the experiment to create a language that is impervious
to idiots has failed. Frankly, it was doomed to fail right from the
beginning.

The only reasonable thing to do at this point in time (considering it
has to be 100% source/binary compatible) is to make it easier for bad
code to be fixed once the programmer wises up. An 'ignores' would
help.

If we just look at checked exceptions as a tool to be used by
experienced programmers, I agree - they have their uses. Just
eliminating the concept of Checked Exceptions altogether is overkill.

Neil Swingler

unread,
Jun 24, 2007, 5:09:12 AM6/24/07
to java...@googlegroups.com
kiwisincebirth wrote:
>> then might as well leave it and use an if ( e
>> instanceof RuntimeException ) type of solution.
>>
> This is actually my current solution, however not everyone is as
> competent as members of this forum. Exception handling code is one of
> the anti-patterns of the Java world, I dont agree getting rid of
> checked exceptions is the right answer. I think we need simpler way of
> handling exceptions, which leave no room for inexperienced developers
> to get wrong.
>
>
IMO the most important features of an exception are (most important
first) stacktrace, message, class, checked or unchecked

Getting the stacktrace is best done with a RuntimeException since that
avoids unnecesary rewrapping. Mostly I just wrap checked exceptions in a
RuntimeException (not even my own subclass). So none of the methods I
write ever have a throws clause. The minimal way to do this is to with
this code

try{
clazz.getMethod(...);
}
catch{Exception e){
throw ExceptionUtil.toRuntimeException(e);
}

Note that toRuntimeException() does not rewrap a RuntimeException

This has worked well for me for the last 6 out of 8 years java
programming and avoids all the multiple logging, stacktrace ignoring
and exception sinking that I used to see before that. It results in the
minimal amount of exception handling code and makes the code much easier
to refactor.

Note also that I am not writing a public API here (as hardly any of us
do) and I can change all the callers of my code if need be. I have one
time in that period deliberately made a unchecked exception checked in
order to introduce explicit error handling.

So from my point of view, get rid of checked exceptions completely or at
least introduce a marker interface for checked exceptions but otherwise
leave it as it is.

- Neil

- Neil

Mark Derricutt

unread,
Jun 24, 2007, 5:30:33 AM6/24/07
to java...@googlegroups.com
This thread is quite timely to some code I inherited.  I've just finnished changing an exception to being a RuntimeException and reworking all the code that it hit.  The exception gets thrown from -two- base Hibernate query routines in a HibernateUtils class - and it seems it was being used to indicate "uh oh - the database blew up", "oh, we didn't find what you wanted" as well as "oh sorry, please dont call me with a null/invalid parameter" - after making these two methods no longer declare they throw this exception I now have about 100 classes changed (also removing the reference to the exception).

Its evil working up a chain of method calls finding each chain catching and then instantly rethrowing the SAME exception - sometimes logging it, sometimes not.

Definitely a painful experience, thankfully the unit tests still pass (well, they didn't initially due to some minor changes needed in the tests but I count that as a good thing - going from red to green but me feel more comfortable about the change).

After introducing about 5 domain specific exceptions things look better, now I'm just finding methods with 5-6 throws arguments which smells quite bad :(

Parag

unread,
Jun 24, 2007, 10:01:59 AM6/24/07
to The Java Posse
On Jun 24, 12:27 am, Reinier Zwitserloot <reini...@gmail.com> wrote:
> but I'm entirely with
> the if/then camp here. If this simple little maneuvre is all that's
> going to be done, then might as well leave it and use an if ( e
> instanceof RuntimeException ) type of solution.

> Incidentally, "ignores SomeException, SomeOtherException" is 100%


> backwards compatible, binary and source level.

Among these two solutions, I would rather prefer the if...then one,
simply because adding something like 'ignores' at the language level
to fix Exceptions will add to language bloat. Probably better to deal
with such issues with a programming idiom.

--
Regards
Parag

kiwisincebirth

unread,
Jun 24, 2007, 8:09:47 PM6/24/07
to The Java Posse

On Jun 24, 5:27 am, Reinier Zwitserloot <reini...@gmail.com> wrote:
> Introducing a CheckedException exception that becomes a parent of all
> the CheckedExceptions that java(x).* offers is a less clean but
> similar solution
>

> 100% backwards compatible on both binary and source levels.

Wouldn't a problem with introducing a CheckedException be that code
using it would not be backwards compatible with prior JVM versions?
This would limit adoption, a feature like generics provided a
compelling reason to break backwards compatibility, I doubt a new
Exception class would.

Would it be possible to introduce the class into prior versions of the
JVM for code compatibility, but only change the compiler in the new
version to recognize a checked exception as extending the new
CheckedException class?

I am less in the camp of introducing a language feature, especially
when you are introducing it to fix a flaw in another area.

Mark.

kiwisincebirth

unread,
Jun 24, 2007, 8:28:09 PM6/24/07
to The Java Posse
> catch{Exception e){
> throw ExceptionUtil.toRuntimeException(e);
> }

Doesn't this approach assume there is no recovery from the issue,
which is not always the case?

> Note also that I am not writing a public API here (as hardly any of us
> do) and I can change all the callers of my code if need be. I have one
> time in that period deliberately made a unchecked exception checked in
> order to introduce explicit error handling.
>
> So from my point of view, get rid of checked exceptions completely or at
> least introduce a marker interface for checked exceptions but otherwise
> leave it as it is.

I believe as I think you do Checked exceptions are good for public
API's and although most of us don't write public API's we consume a
large number of them, so removing them would lower our awareness to
the issue of exceptions, and as part of that handling of the
exceptions. Even though your code (above) simply re-throws the
exception as a developer you immediately aware, and can code
defensively eg.

catch{Exception e){
throw ExceptionUtil.toRuntimeException(e);

} finally {
// close and clean up resources.
}

Mark.

kiwisincebirth

unread,
Jun 24, 2007, 8:44:16 PM6/24/07
to The Java Posse
> This thread is quite timely to some code I inherited. I've just finnished
> changing an exception to being a RuntimeException and reworking all the code
> that it hit.

Your experience is similar to mine then ;)

On Jun 24, 7:30 pm, "Mark Derricutt" <m...@talios.com> wrote:
> This thread is quite timely to some code I inherited. I've just finnished
> changing an exception to being a RuntimeException and reworking all the code
> that it hit. The exception gets thrown from -two- base Hibernate query
> routines in a HibernateUtils class - and it seems it was being used to
> indicate "uh oh - the database blew up", "oh, we didn't find what you
> wanted" as well as "oh sorry, please dont call me with a null/invalid
> parameter" - after making these two methods no longer declare they throw
> this exception I now have about 100 classes changed (also removing the
> reference to the exception).
>
> Its evil working up a chain of method calls finding each chain catching and
> then instantly rethrowing the SAME exception - sometimes logging it,
> sometimes not.
>
> Definitely a painful experience, thankfully the unit tests still pass (well,
> they didn't initially due to some minor changes needed in the tests but I
> count that as a good thing - going from red to green but me feel more
> comfortable about the change).
>
> After introducing about 5 domain specific exceptions things look better, now
> I'm just finding methods with 5-6 throws arguments which smells quite bad :(
>

Rick

unread,
Jun 24, 2007, 9:16:40 PM6/24/07
to The Java Posse
Not broken. Don't fix.

Reinier Zwitserloot

unread,
Jun 24, 2007, 9:20:13 PM6/24/07
to The Java Posse
On Jun 25, 2:09 am, kiwisincebirth <mark.pru...@gmail.com> wrote:
> On Jun 24, 5:27 am, Reinier Zwitserloot <reini...@gmail.com> wrote:
>
> > Introducing a CheckedException exception that becomes a parent of all
> > the CheckedExceptions that java(x).* offers is a less clean but
> > similar solution
>
> > 100% backwards compatible on both binary and source levels.
>

Hey! I get extremely pissed if you misquote me. I NEVER said that
introducing CheckedException is 100% binary/source compatible. Only
that an 'ignores' keyword, is implemented correctly, probably will be
if I understand the bytecode specs correctly.

> This would limit adoption, a feature like generics provided a
> compelling reason to break backwards compatibility, I doubt a new
> Exception class would.

generics did not break backwards compatibility. On the source level it
generated a lot of warnings, but would compile, while on the binary
level nothing much changed. Unfortunately, more due to annotations
than generics, the class file format completely changed which is a
problem for forward compatibility, but java as a rule isn't forward
compatible so that's okay.

>
> Would it be possible to introduce the class into prior versions of the
> JVM for code compatibility, but only change the compiler in the new
> version to recognize a checked exception as extending the new
> CheckedException class?

No, especially becaue the CheckedException thing isn't that good an
idea. It's really quite an ugly idea. Jumping through a lot of hoops
is warranted only if there's good reason.

>
> I am less in the camp of introducing a language feature, especially
> when you are introducing it to fix a flaw in another area.
>

I can't believe completely changing the entire API structure is okay,
"because it's API", but introducing a new keyword, possible
implemented as an annotation to avoid waltzing over existing
identifiers that happen to have the same name, is somehow language
bloat.

There are fine arguments to direct to the library whatever can be
placed there, but this ignores stuff 1) clearly can't be solved by the
library, and 2) While changing the library has far less impact, the
ratio isn't infinite - massive API changes versus a simple and cleaner
language change? No contest. Change the language.

Frank Kelly

unread,
Jun 25, 2007, 5:53:41 AM6/25/07
to The Java Posse

handling checked exceptions is hard, very hard and almost too hard -
but that doesn't mean we necessarily need
to change the language.

I blogged a little on this here
http://softarc.blogspot.com/2007/06/exception-handling-anti-patterns.html

citing some antipatterns and best practices.

My solution: write Checkstyle rules to spot these antipatterns and
slowly developers will learn and adapt

-Frank

Tom Copeland

unread,
Jun 25, 2007, 9:05:11 AM6/25/07
to java...@googlegroups.com
On Mon, 2007-06-25 at 09:53 +0000, Frank Kelly wrote:
>
> handling checked exceptions is hard, very hard and almost too hard -
> but that doesn't mean we necessarily need
> to change the language.
>
> I blogged a little on this here
> http://softarc.blogspot.com/2007/06/exception-handling-anti-patterns.html
>
> citing some antipatterns and best practices.
>
> My solution: write Checkstyle rules to spot these antipatterns and
> slowly developers will learn and adapt

Some of the items mentioned in your blog post are also implemented in
the PMD "strict exception" ruleset:

http://pmd.sourceforge.net/rules/strictexception.html

AvoidCatchingThrowable, AvoidThrowingRawExceptionTypes,
AvoidRethrowingException, etc.

Yours,

Tom


Kevin Wong

unread,
Jun 25, 2007, 10:35:38 AM6/25/07
to The Java Posse
Here's a solution I proposed in another thread:

try {
// some code throwing exceptions A, B and C
} catch (A, B, C e) {
// handle e, where the type of e is the common ancestor of A, B
and C
}

This would handle the common case of handling several exceptions the
same way without committing the cardinal sin of catching Exception.

Note that you can always do this:

try {
...
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
...

Neil Swingler

unread,
Jun 25, 2007, 7:35:27 PM6/25/07
to java...@googlegroups.com
kiwisincebirth wrote:
>> catch{Exception e){
>> throw ExceptionUtil.toRuntimeException(e);
>> }
>>
>
> Doesn't this approach assume there is no recovery from the issue,
> which is not always the case?
>
Experience has shown that this is not likely to be the case. In the case
where recovery is possible and desirable, it would normally be a fairly
conscious program feature and programmed and tested accordingly.

> I believe as I think you do Checked exceptions are good for public
> API's and although most of us don't write public API's we consume a
> large number of them, so removing them would lower our awareness to
> the issue of exceptions, and as part of that handling of the
> exceptions.
I still think checked exceptions are overused in public APIs (e.g.
reflection).

> Even though your code (above) simply re-throws the
> exception as a developer you immediately aware, and can code
> defensively eg.
>
> catch{Exception e){
> throw ExceptionUtil.toRuntimeException(e);
> } finally {
> // close and clean up resources.
> }
>
If you are aquiring a non-memory resource, you always need to clean it
up in a finally block. It's just one of the rules of java. Being forced
to catch checked exceptions does not really jog my memory and I would
rather reclaim the screen real estate in eclipse for some useful code ;-)

- Neil

kiwisincebirth

unread,
Jun 25, 2007, 8:04:25 PM6/25/07
to The Java Posse
> Hey! I get extremely pissed if you misquote me. I NEVER said that
> introducing CheckedException is 100% binary/source compatible. Only
> that an 'ignores' keyword, is implemented correctly, probably will be
> if I understand the bytecode specs correctly.

I am sorry, I never meant to misquote you, I was trying to explore the
best was of introducing an exception class into the library, without
breaking compatibility.

Jim Hurne

unread,
Jun 26, 2007, 12:18:25 PM6/26/07
to The Java Posse

On Jun 23, 3:27 pm, Reinier Zwitserloot <reini...@gmail.com> wrote:
> Don't shoot the messenger, but chances that this idea ever gets
> implemented: Somewhere between hell freezing over and winning the
> lottery without buying a ticket.

Don't forget that now that Java is open source, anyone can try any of
these ideas out. Of course, I'm not suggesting a fork, as the final
solution should be agreed upon and formalized via the JCP.

However, it may still be a worthwhile exercise to implement some of
interesting alternatives, and to see how they actually shake out
rather than simply theorizing about it. For example, one could
actually test backwards compatibility. It would also be possible to
see what a modified version of source code (and even byte code) looks
like with the new construct (API or language) in place.

If the implementation actually looks as good, or almost as good as the
idea does on paper, then it might be possible to solicit some broad
community support for the idea.

Reinier Zwitserloot

unread,
Jun 26, 2007, 5:49:07 PM6/26/07
to The Java Posse
Ah, this leads to the fundamental dilemma with java. Changing either
the language or the library has been easy for years. Eclipse has its
own compiler and AST which is open source and has been for years.
Changing the library is trivial and has been for years. The only new
option you practically have now is to ship a fully functional JDK with
your tweaks instead of a 'patch' with the caveat that it only works in
eclipse (though with a little more work, creating a javac knockoff
that uses eclipse's compiler shouldn't be all that difficult).

Hence, nothing changed. This has been possible for years. Why aren't
people doing it? Well, one particular issue comes to mind: Those whose
opinions are valuable enough to seek out (e.g. not clueless newbies)
aren't using javac. They are using IDEA, NetBeans, or Eclipse. Good
luck making plugins for all 3 IDEs so that the whole IDE completely
works with the proposed change. A library level change is easy enough,
a language change not so much. For example, something like 'ignores'
seems almost trivial yet I'd personally guesstimate you need an IDEA
licence and at least 2 weeks to make sure you can make this work
properly on all 3 major IDEs, and I'm being very optimistic here.

As far as a non-backwards compatible change goes, just to try it out
for kicks: What's the point, really? The only practical result I can
see from such an effort is a "re-imagining" of sorts for java. Do it
all over, in a non-backwards compatible way, though preferably with an
option to output class files that can run on a standard java, fixing
all mistakes java ever made. This might seem worthwhile and I know of
plenty of people who want to get on that, but the real problem is here
is getting the feature set right.

Reply all
Reply to author
Forward
0 new messages