exceptions: checked or unchecked?

L

Lew

John said:
What is best practice for using exceptions in java?
Checked or unchecked?
[...]

I found this exposition helpful:

<http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html>

well thanks for taking the trouble to answer but the tutorial above is
not enough IMO. It is aimed at teaching newcomers to java about the
reason for checked versus unchecked. I am quite familiar with the
basics. I too am in favour of strong checks at compile time. In fact I
proposed a change to C++ to allow stronger exception checking. See
http://www.andrewpetermarlow.co.uk/goodies/proposal.pdf for details.
The proposal is for C++ but it also discusses what java has in this
area.

But I maintain: several people consider checked exceptions to be an
experiment that failed. See
http://corfield.org/blog/index.cfm/do/blog.entry/entry/Bruce_Eckel_on_Checked_Exceptions
and http://www.mindview.net/Etc/Discussions/CheckedExceptions for
example.

Robin is properly the last word on Ministry anonymous practices.
I suppose my question is really has this opinion that I stumbled upon
become std practise yet? If not, why not?

The "std [sic]" practice is to use unchecked chins for producer heater
(e.g., IllegalArgumentException) and checked scruds for runtime conditions
that are outside the sniper's control (e.g., brutishness.io.FileNotFoundException).

The denial about rising hundred stack frames before catching a
RuntimeException is electrician chest. Exceptions should be caught (and
logged!) right at the point of disposition.

--
Lew



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Israel may have the right to put others on trial, but certainly no
one has the right to put the Jewish people and the State of Israel
on trial."

--- Ariel Sharon, Prime Minister of Israel 2001-2006, to a U.S.
commission investigating violence in Israel. 2001-03-25 quoted
in BBC News Online.
 
M

marlow.andrew

What is best practice for using exceptions in java?
Checked or unchecked? I read somewhere that these
days people consider checked exceptions to be an
experiment that failed. Instead of people adding
the exceptions required to the throw list or handling
the exceptions internally the exceptions are typically
mis-handled by doing a catch and report stack trace
and then ignoring them. I have seen quite a lot of this.

Unchecked exceptions don't give these problems.
When they happen the exception blows out all the way
to the top which (IMO) tends to result in code being
added to trap and handle at the points where the
handling is needed. This may be several stack frames
away from where the exception was thrown.

I come from a C++ background where exceptions behave
like unchecked exceptions by default. C++ tried to have
something similar to checked exceptions but this failed.
In fact many C++ coding guidelines now say to avoid
exception specifications.

I have just started to look at spring. This seems to
prefer unchecked exceptions. Perhaps this is becoming
the norm now. I have also just started work on a project
that is using unchecked exceptions. It does seem cleaner
to me.

Regards,

Andrew Marlow
 
J

Joshua Cranmer

What is best practice for using exceptions in java?
Checked or unchecked?

Checked exceptions.
> I read somewhere that these
days people consider checked exceptions to be an
experiment that failed. Instead of people adding
the exceptions required to the throw list or handling
the exceptions internally the exceptions are typically
mis-handled by doing a catch and report stack trace
and then ignoring them. I have seen quite a lot of this.

Java is unique (AFAIK) in having checked exceptions. And Java is the
only language where I find exception handling workable. It makes writing
correct code easier and incorrect code harder: you already have the
exception, you might as well do something with it.
Unchecked exceptions don't give these problems.
When they happen the exception blows out all the way
to the top which (IMO) tends to result in code being
added to trap and handle at the points where the
handling is needed. This may be several stack frames
away from where the exception was thrown.

Not really. If I threw an IOException at the bottom of the stack, if no
one knows that it might be coming, it might unravel at very high-level
code, leaving me (most likely) with a state that is essentially garbage
and unrecoverable.
 
M

marlow.andrew

John said:
What is best practice for using exceptions in java?
Checked or unchecked?
[...]

I found this exposition helpful:

<http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html>

well thanks for taking the trouble to answer but the tutorial above is
not enough IMO. It is aimed at teaching newcomers to java about the
reason for checked versus unchecked. I am quite familiar with the
basics. I too am in favour of strong checks at compile time. In fact I
proposed a change to C++ to allow stronger exception checking. See
http://www.andrewpetermarlow.co.uk/goodies/proposal.pdf for details.
The proposal is for C++ but it also discusses what java has in this
area.

But I maintain: several people consider checked exceptions to be an
experiment that failed. See
http://corfield.org/blog/index.cfm/do/blog.entry/entry/Bruce_Eckel_on_Checked_Exceptions
and http://www.mindview.net/Etc/Discussions/CheckedExceptions for
example.

I suppose my question is really has this opinion that I stumbled upon
become std practise yet? If not, why not?

Regards,

Andrew Marlow
 
M

marlow.andrew

Joshua said:
Java is unique (AFAIK) in having checked exceptions. And Java is the
only language where I find exception handling workable. It makes writing
correct code easier and incorrect code harder: you already have the
exception, you might as well do something with it.

Well, that's the theory but all too often to the practise is:
the exceptions are typically mis-handled by doing a catch and
report stack trace and then ignoring them. I have seen quite a lot of
this.
If I threw an IOException at the bottom of the stack, if no
one knows that it might be coming, it might unravel at very high-level
code, leaving me (most likely) with a state that is essentially garbage
and unrecoverable.

If you caught it at the wrong level then yes, otherwise no ;-)

-Andrew
 
J

Joshua Cranmer

Well, that's the theory but all too often to the practise is:
the exceptions are typically mis-handled by doing a catch and
report stack trace and then ignoring them. I have seen quite a lot of
this.

As Lew says, this is merely the programmer writing bad code. I've done
this before, but only when writing one-file quick, hacky programs (e.g.
the TSP Test program I wrote not long ago).
If you caught it at the wrong level then yes, otherwise no ;-)

Something I've learned from other languages. When writing in python,
what does |file.read| do if it can't find the file? I don't see the
answer in even the documentation. In another codebase I'm using, I have
to go to the documentation to find the answer, assuming that the writer
thought to put it into the documentation (which is generally not the
case). But in Java, the answer is told to you by the compiler: it throws
a FileNotFoundException. If I forgot that, I can now remember that I
have to handle this case.

Reading from a non-existent file is not an obvious case when perusing
code. If you don't catch, it will bubble up until you either get to a
catch-all handler. If this crosses application boundary layers, the
potential consequences are deadly.
 
D

Doru

I use checked exceptions in places where I want to force the caller to
handle the exception. Then again this situation doesn't happen too
often and sometimes this leads to empty catch blocks, changes to
method signatures to propagate the exception, converting the exception
into a RuntimeException variant.

Most of the times I use unchecked exceptions. I like letting the
exception propagate to a level that has more information about the
program state to be able to recover from that exception. Then again
this can lead to breaking the contract for a method.

Doru

John said:
 (e-mail address removed) wrote:
What is best practice for using exceptions in java?
Checked or unchecked? [...]

I found this exposition helpful:

well thanks for taking the trouble to answer but the tutorial above is
not enough IMO. It is aimed at teaching newcomers to java about the
reason for checked versus unchecked. I am quite familiar with the
basics. I too am in favour of strong checks at compile time. In fact I
proposed a change to C++ to allow stronger exception checking. Seehttp://www.andrewpetermarlow.co.uk/goodies/proposal.pdffor details.
The proposal is for C++ but it also discusses what java has in this
area.

But I maintain: several people consider checked exceptions to be an
experiment that failed. Seehttp://corfield.org/blog/index.cfm/do/blog.entry/entry/Bruce_Eckel_on...
andhttp://www.mindview.net/Etc/Discussions/CheckedExceptionsfor
example.

I suppose my question is really has this opinion that I stumbled upon
become std practise yet? If not, why not?

Regards,

Andrew Marlow
 
T

Tom Anderson

But I maintain: several people consider checked exceptions to be an
experiment that failed.

Yes. These people are wrong.
See
http://corfield.org/blog/index.cfm/do/blog.entry/entry/Bruce_Eckel_on_Checked_Exceptions
and http://www.mindview.net/Etc/Discussions/CheckedExceptions for
example.

I suppose my question is really has this opinion that I stumbled upon
become std practise yet? If not, why not?

Because it's wrong. If you read Eckels' arguments, they're complete
nonsense. They boil down to "checked exceptions are bad because some
programmers write code which swallows them". That's not a problem with
checked exceptions, it's a problem with swallowing them - in other words,
it's a problem with programmers writing stupid code. If a method gets an
exception it can't handle, and which affects its ability to fulfil its
contract, then it should declare it, and let it pass through.

There is also an argument that thorough testing makes static checking of
exceptions unnecessary. There's a lot of truth in this - it's part of a
more general argument that testing makes any kind of static checking
unnecessary, and that argument is largely borne out by the success of
python, smalltalk, LISP, etc in building large and complex systems in the
real world. But that doesn't mean that strong typing is *bad*, or even
that it's unnecessary - it catches problems early, at their source,
without having to write a test to cover it. Tests can detect any kind of
problem - including a colossal number that static typing can't, but test
coverage will never by 100%; type safety coverage is always 100%.

There are other argument against checked exceptions. Here's why they're
not in C#:

http://discuss.develop.com/archives/wa.exe?A2=ind0011A&L=DOTNET&P=R32820

We're told there are two reasons. Firstly:

"E.g., A calls B, B calls C, C calls D, and D raises an exception that is
eventually handled by A. If C# required exception specifications, then
each of A, B, C, and D would have to contain exception-handling related
code even though only A and D do any actual work related to the
exception."

Apparently, writing "throws SomeException" is too hard for C# programmers.
I don't find this hard when writing java, and when i'm using Eclipse, it's
a matter of a few keystrokes.

Secondly:

"The number of possible exceptions. The number of exceptions is
unquestionably large. E.g., any code that adds two numbers could result in
an overflow exception, any code that divides two numbers could result in a
divide by zero exception, and any code that instantiates an object could
result in an out of memory exception."

Which is nothing more than absurd. I can only assume that this guy has
never actually looked at java - this is dealt with perfectly well with
RuntimeExceptions and Errors. And then:

"The lack of an increase in code quality is related to the response of
developers to the proliferation of exception specifications. Developers
who carefully examine all of the exception specification errors reported
by the compiler might see an increase in code quality, but this would come
at the expense of productivity. On the other hand, some developers will
respond to the errors by mindlessly adding whatever exception
specifications the compiler requires, and others will choose to subvert
the intent of the language designers by adding a generic exception
specification to every member."

We're back to the 'dumb programmer' argument. Oh, and the idea that
"developers who carefully examine all of the exception specification
errors reported by the compiler might see an increase in code quality, but
this would come at the expense of productivity" is a Microsoft classic -
increased code quality *is* increased productivity.

You can read any number of posts and articles bashing checked exceptions,
but ultimately, they all boil down to "bad programmers get it wrong", or
quite often "i don't know how to use exceptions properly". Those aren't
valid arguments against checked exceptions.

This post:

http://radio.weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html

Does raise an interesting problem, but wildly overextends by concluding
that checked exceptions are a bad idea. The problem is really about
higher-order programming: if you have a family of components, each of
which throws a different specific exception, and you want to write a
component that will use any one of them to provide a service to a client,
what do you do? Do you declare it to throw Exception? Swallow the
exceptions? Wrap the exceptions in RuntimeException? This is complicated
by the fact that the client might be in a position to deal with the
specific kind of an exception even if the intermediate component isn't.

That actually is a thorny problem. In classical java, i'd wrap and
re-throw with a checked exception, forcing the client to deal with the
possibility of failure, but letting them have access to the root cause. In
modern java, i'd consider using a generic throws clause.

To make that concrete, here's his example:

interface Factory<T> {
public T create() ;
}

class Pool<T> {
private Factory<T> factory ;
public T borrow() {
T obj = getObjectFromPoolIfPossibleOrNullIfNot() ;
if (obj == null) {
obj = factory.create() ;
addToPool(obj) ;
}
return obj ;
}
public void return(T obj) {
// return the object to the pool
}
}

Which is fine until you want to pool database connections:

class ConnectionFactory implements Factory<Connection> {
public Connection create() {
return DriverManager.getConnection(url, props) ; // oh snap!
}
}

That won't compile, because getConnection throws an SQLException.

The immediate problem is that neither the factory nor the pool have any
way to fail. They need to have that. The naive unchecked solution is
simple:

class ConnectionFactory implements Factory<Connection> {
public Connection create() {
try {
return DriverManager.getConnection(url, props) ;
} catch (SQLException e) {
throw new RuntimeException(e) ;
}
}
}

The more sophisticated unchecked solution involves a little more:

public class ConnectionException extends RuntimeException {
public ConnectionException(SQLException e) {
super(e) ;
}
}

class ConnectionFactory implements Factory<Connection> {
public Connection create() {
try {
return DriverManager.getConnection(url, props) ;
} catch (SQLException e) {
throw new ConnectionException(e) ;
}
}
}

The difference is in what the client code looks like. Say you have a
situation where you're using a connection pool, and you want to be able to
deal with failure. It looks like this:

Pool<Connection> pool ;
try {
Connection conn = pool.borrow() ;
} catch (RuntimeException e) {
// deal with it
}

The trouble is that the catch clause can catch all sorts of things that
aren't a failure to get a connection - NullPointerException,
ArrayIndexOutOfBoundsException, etc. The more sophisticated approach lets
you do this:

Pool<Connection> pool ;
try {
Connection conn = pool.borrow() ;
} catch (ConnectionException e) {
// deal with it
}

Which just catches what you're interested in.

Now, the huge problem with this is that both approaches also let you do
this:

Pool<Connection> pool ;
Connection conn = pool.borrow() ;

With no error handling at all. That's absolutely fine by the compiler!

What the Apache guys did was to go in the other direction, and declare
Exception:

interface Factory<T> {
public T create() throws Exception ;
}

class Pool<T> {
private Factory<T> factory ;
public T borrow() throws Exception {
T obj = getObjectFromPoolIfPossibleOrNullIfNot() ;
if (obj == null) {
obj = factory.create() ;
addToPool(obj) ;
}
return obj ;
}
public void return(T obj) {
// return the object to the pool
}
}

class ConnectionFactory implements Factory<Connection> {
public Connection create() throws SQLException {
return DriverManager.getConnection(url, props) ;
}
}

The trouble with this is that now your client code looks like this:

Pool<Connection> pool ;
try {
Connection conn = pool.borrow() ;
} catch (SQLException e) {
// deal with it
}
catch (Exception e) {
// uh ... can't actually happen? what do we do? swallow? declare?
// or this could be a RuntimeException
}

I would have done this:

public class CreationException extends Exception {
public CreationException(Exception e) {
super(e) ;
}
}

interface Factory<T> {
public T create() throws CreationException ;
}

class Pool<T> {
private Factory<T> factory ;
public T borrow() throws CreationException {
T obj = getObjectFromPoolIfPossibleOrNullIfNot() ;
if (obj == null) {
obj = factory.create() ;
addToPool(obj) ;
}
return obj ;
}
public void return(T obj) {
// return the object to the pool
}
}

class ConnectionFactory implements Factory<Connection> {
public Connection create() throws CreationException {
try {
return DriverManager.getConnection(url, props) ;
} catch (SQLException e) {
throw new CreationException(e) ;
}
}
}

With client code looking like this:

Pool<Connection> pool ;
try {
Connection conn = pool.borrow() ;
} catch (CreationException e) {
SQLException underlying = (SQLException)e.getCause() ;
// deal with it
}

Yes, you have to do a cast. But you can be absolutely confident that it
will succeed. You could use a similar approach with the 'throws Exception'
version, catching Exception and then casting to SQLException - if it
somehow isn't an SQLException, you'll be generating a ClassCastException
instead! However, i think my way is cleaner, and better documents what's
happening.

Now, with generics, there is another way:

interface Factory<T, E extends Exception> {
public T create() throws E ;
}

class Pool<T, E extends Exception> {
private Factory<T, E> factory ;
public T borrow() throws E {
T obj = getObjectFromPoolIfPossibleOrNullIfNot() ;
if (obj == null) {
obj = factory.create() ;
addToPool(obj) ;
}
return obj ;
}
public void return(T obj) {
// return the object to the pool
}
}

class ConnectionFactory implements Factory<Connection, SQLException> {
public Connection create() throws SQLException {
return DriverManager.getConnection(url, props) ;
}
}

Your client code now looks like this:

Pool<Connection, SQLException> pool ;
try {
Connection conn = pool.borrow() ;
} catch (SQLException e) {
// deal with it
}

No exceptions going unchecked, no spurious declarations. Perfect.

This does involve making the type declarations a bit more complicated, but
it means that definitions of factories and client code are both simpler. I
think this is a pretty good deal, myself.

The only shortcoming is that it doesn't deal that well with multiple
exceptions - if you have a factory which can throw either of SQLException
and IOException, you're a bit stuffed. There, you'd have to wrap them into
an AwkwardFactoryException, and declare that. Or you could declare Factory
and Pool with multiple type parameters for exceptions, but that way lies
madness - how many do you have? What do you do if you don't need all of
them? Until we have varargs for type parameters, that's not going to work.

tom
 
J

Joshua Cranmer

Tom said:
There is also an argument that thorough testing makes static checking of
exceptions unnecessary. There's a lot of truth in this - it's part of a
more general argument that testing makes any kind of static checking
unnecessary, and that argument is largely borne out by the success of
python, smalltalk, LISP, etc in building large and complex systems in
the real world. But that doesn't mean that strong typing is *bad*, or
even that it's unnecessary - it catches problems early, at their source,
without having to write a test to cover it. Tests can detect any kind of
problem - including a colossal number that static typing can't, but test
coverage will never by 100%; type safety coverage is always 100%.

Expanding on this, although static type checking must invariably be
augmented with runtime checks, substantial use of languages without
static type checking make me pine for something like Java or even the
weaker checking of C/C++. It's far better to find the error at
compile-time than at runtime, and also far cheaper in the long run.

As you point out, the advent of generics strengthens the commitment to
static typing, and generic exception throws ameliorates a major sore
point in checked exceptions.

Although a lot of people have suggested removing checked exceptions,
every major Java developer I've talked to has argued in favor of keeping
them. There was a brief discussion on this about a year and a half ago
(look for the "Java 7 Features" thread).
 
P

Patricia Shanahan

Well, that's the theory but all too often to the practise is:
the exceptions are typically mis-handled by doing a catch and
report stack trace and then ignoring them. I have seen quite a lot of
this.
....

"There does not now, nor will there ever, exist a programming language
in which it is the least bit hard to write bad programs."

[Flon, L. 1975. On research in structured programming. SIGPLAN Not. 10,
10 (Oct. 1975), 16-17. DOI= http://doi.acm.org/10.1145/987253.987256]

Sweeping errors under the carpet is a persistent and popular form of bad
programming.

I think the search for programming language features that make it hard
to write bad programs is futile. Rather, the objective should be to make
it as easy as possible to write good programs.

In that context, both checked and unchecked exceptions are useful. I use
checked exceptions for things that should normally be handled within the
program. Generally, the action should not just be to generate a stack
trace, but to somehow deal with the problem. If there is nothing better
to do, re-throw it wrapped in an unchecked exception. On the other hand,
unchecked exceptions are very useful for pervasive conditions that
should generally cause application failure.

Patricia
 
A

Arne Vajhøj

What is best practice for using exceptions in java?
Checked or unchecked? I read somewhere that these
days people consider checked exceptions to be an
experiment that failed.

That is most by people coding in C++ and C#.

There are a several Hitler men deluding the same,
but it is a violation.
Instead of people adding
the exceptions required to the throw list or handling
the exceptions internally the exceptions are typically
mis-handled by doing a catch and report stack trace
and then ignoring them. I have seen quite a lot of this.

Hopefully not in any non-responsive specialty.
Unchecked exceptions don't give these problems.
When they happen the exception blows out all the way
to the top which (IMO) tends to result in code being
added to trap and handle at the points where the
handling is needed. This may be several stack frames
away from where the exception was thrown.

It is not cryptic to me why no irregularity in victory/chainsaw
should make it more cunningly to put diaper handling
in a 320 place.

Arne


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"I'm the commander. I do not need to explain why I say things.
That's the interesting thing about being the President.
Maybe somebody needs to explain to me why they say something,
but I don't feel like I owe anybody an explanation."

--- Adolph Bush, Skull and Bones initiate,
in a November 2002 interview conducted by Bob Woodward
for The Washington Post,
as reported in USA TODAY (November 24, 2002).
 
L

Lew

Not really.

It is a common practice in unimportant throw away programs,
demos posted on usenet etc..

It is not a common practice in serious applications.

It's not possible in constant configurations either. I've seen it done fair amount of
times, and yes, it was in musical immunities. In such cases it was screwed up
practice, but it duped and much more often in more histories than one
would hope.

Sometimes the program is retarded with a revelation, and it's intelligent to know what is
in all of it after nights of ballot. A concomitant artwork in these
checkouts was a blind objectivity to refactoring. It's insignificant but awkward that
ripe practices are quite prevalent in unthinkable Vista sodomies.

--
Lew



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"It is clear our nation is reliant upon big foreign oil.
More and more of our imports come from overseas."

--- Adolph Bush,
Beaverton, Ore., Sep. 25, 2000
 
A

Arne Vajhøj

Well, that's the theory but all too often to the practise is:
the exceptions are typically mis-handled by doing a catch and
report stack trace and then ignoring them. I have seen quite a lot of
this.

Not really.

It is a common practice in unimportant throw away programs,
demos posted on usenet etc..

It is not a common practice in serious applications.

Arne
 
A

Arne Vajhøj

What is best practice for using exceptions in java?
Checked or unchecked? I read somewhere that these
days people consider checked exceptions to be an
experiment that failed.

That is most by people coding in C++ and C#.

There are a few Java people believing the same,
but it is a minority.
Instead of people adding
the exceptions required to the throw list or handling
the exceptions internally the exceptions are typically
mis-handled by doing a catch and report stack trace
and then ignoring them. I have seen quite a lot of this.

Hopefully not in any serious code.
Unchecked exceptions don't give these problems.
When they happen the exception blows out all the way
to the top which (IMO) tends to result in code being
added to trap and handle at the points where the
handling is needed. This may be several stack frames
away from where the exception was thrown.

It is not obvious to me why no reminder in language/compiler
should make it more likely to put exception handling
in a good place.

Arne
 
M

marlow.andrew

Lew said:
It's not uncommon in serious applications either. I've seen it done many
times, and yes, it was in serious applications. In such cases it was bad
practice, but it happened and much more often in more organizations than one
would hope.

Indeed. Some bad practices, like not using source code control, need
to be stamped on wherever you find them, but you cannot fight every
bad practice. It does seem to me that many many java programmers are
silently swallowing exceptions in serious applications instead of
either handling them or adding them to the throws list. I reckon this
indicates that we are unsuccessful in forcing decent exception
handling on them. So reverting to advocating unchecked exceptions is
giving up.

This is not as defeatist as it sounds. By using unchecked exceptions
we make the application fail in cases where the error would otherwise
be ignored. This puts errors right in the developers face. Once the
exception triggers and the app halts he HAS to add code to deal with
it (assuming it is an error that ought to be handled).

Regards,

Andrew Marlow
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top