IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New Because checked exceptions are STOOPID!
I've been railing about this for a long time. Some people can't seem to see the point (no not people here).

My pet peeve is shit like this:

InputStream>>public abstract int read(byte[] bytes, int pos, int len) throws IOException

OK, so we've defined an abstract class for reading bytes into an array. Its really more of an interface here. Thinking ahead that we will use this to read files and sockets they have it throw IOException because you never can tell with file systems.

Later on we have ByteArrayInputStream>>public int read(byte[] bytes, int pos, int len)...

Now we know that reading from a byte array in memory is pretty safe - certainly won't cause any kind of IO error. So this method absolutely will NOT throw an IOException - but when using said class I still have to catch the bloody thing:

InputStream in = new ByteArrayInputStream(myBytes);
try { in.read(buffer,0,buffer.length); } catch(IOException ex) { /* Fookin J-Heads */ }

Stupid language "feature" bug.



The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
New One reason I like Spring Framework
They're all about unchecked exceptions, and they've written a good amount of code to make things like JDBC behave in an unchecked manner.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Absolutely
We have reams of code which catches a lower level exception and wraps it in a higher level one. Basically every level wraps the exceptions below it. For example our database layer (in theory, unfortunately many of the methods just throw 10 exceptions (SQLException, NameNotFoundException etc.) so you have application code having to catch SQLExceptions, EJBExceptions etc) catches all Exceptions and wraps them in some general exception. The layer above that does the saem and so on.
New Re: Because checked exceptions are STOOPID!
Your example is of a poorly implemented "interface" and the poor use of checked exceptions. However, I've not heard one respectable reason against the *concept* of checked exceptions (their misuse doesn't count as one).

Dan
New One respectable reason
Fragile method signatures.

[link|http://www.mindview.net/Etc/Discussions/CheckedExceptions|Bruce Eckel] and [link|http://www.octopull.demon.co.uk/java/ExceptionalJava.html|Alan Griffiths] have more to say on the subject. Or read Rod Johnson's book.
Regards,

-scott anderson

"Welcome to Rivendell, Mr. Anderson..."
New Re: One respectable reason
My understanding of the "fragility" of method signature in respect to checked exceptions is that, too often, developers merely rethrow contained exceptions, creating a large list of exceptions (in the throws clause) tacked to the method signatures.

Again, from what I've seen (the the two articles you pointed out are no exceptions...no pun intended), the issues surrounding the fundamental problem with checked exceptions has more to do with how developers deal with them, and not the concept, itself.

For example, the fragility issue should be solved by properly catching exceptions and rethrowing the proper one(s) for the given layer. If development is approached via layers, then each layer should have its own exception hierarchy. This keeps the number of exceptions thrown to a minimum (usually just one).

Bruce complains about code readability and how developers misuse them. My problem with that is that I think they were added to the language for a purpose, and that for developers to ignore them (or treat them improperly) is to make for bad development. So, it's not a problem with checked exceptions, themselves, as it is a problem with training developers to think differently about how they code. Just as test-first coding requires a different mindset, the user of checked exceptions requires the developer to approach development with a particular mindset. More specifically, a high percentage of code exists to handle error conditions (in whatever form). If a developer approaches development is the attitude of "just get the job done," then they'll take shortcuts (some of which will be the misuse of checked exceptions). However, if they approach development with the opinion that there be no holes, and that error handling is a significant part of what they do (just as testing, etc. should be), then checked exception won't get in the way. In fact, they'll help (because the compiler will help them be honest).

Most of the real complaints I've heard are either based upon developers misusing them, and because many libraries and API's don't use them appropriatly (especially the way the Java libraries are...which is admittedly painful).

Of course, I'm not one to say that everything should be a checked exception, either. Unchecked exceptions are important, though I was surprised that Alan Giffiths main thought on them was programmer error. There are two sets of "exceptions" that are non-checked in java: runtime exceptions and errors. One is for programmer errors (runtime exception). Errors are for situations where your app probably can't handle it, such as out of memory errors.

Regardless, I think they both should be used appropriately, but I don't think that checked exceptions are inherently "bad," though they are certainly misused too much (just like C pointers, inheritance, etc.).

Dan
New The problem with Java model is that I cannot
declare exception "not thrown" in the implementation of interface. I do not think a solution is possible within the confines of static type checking, and that makes Java's checked exceptions bad.
--

The number of the beast - vi vi vi
--[link|http://c2.com/cgi/wiki?QuotesOnComputers|Delexa Jones]
New Re: The problem with Java model is that I cannot
I'm not sure why you think that's "bad." I'm assuming it's because, since your implementation of the interface doesn't actually throw the exception, that it would be nice to not have to declare it. However, the client of that interface should view your implemetation as just that interface, in which case, the designer of the interface made the decision that it should be part of the signature (whether they were correct or not is another thing).

In other words, a checked exception in a signature helps define that method, regardless of whether it's used or not (just like parameters can be ignored, but are still there). My point is that it may be the poor design of the interface, or it may be that the designer wanted the user of that interface to be aware (and effectively force them to handle the interface a certain way). I don't see it as a problem with the concept of checked exceptions, though.

Dan
New But that would (i.e, *does*) defeat the whole purpose!
Dan Shell-s out his two cents:
My understanding of the "fragility" of method signature in respect to checked exceptions is that, too often, developers merely rethrow contained exceptions, creating a large list of exceptions (in the throws clause) tacked to the method signatures. [...] the fundamental problem with checked exceptions has more to do with how developers deal with them, and not the concept, itself.
Nope, sorry, you're wrong, it's the concept: You see, "checked" exceptions are inherently at cross-purposes with the main idea behind why exceptions were invented in the first place.

You illustrate this self-contradiction yourself, in the following (only slightly abbreviated) quote:
For example, the fragility issue should be solved by properly catching exceptions and rethrowing the proper one(s) for the given layer. If development is approached via layers, then each layer should have its own exception hierarchy. [...] I think [exceptions] were added to the language for a purpose
Yup, they certainly were.

And that purpose was "Centralised Exception Handling".

The idea was, that in stead of returning error codes or something from each and every function / method (and therefore having to handle them, at least to the extent of returning the same or another error code upon receipt of one, in each and every function / method), you would just "throw an exception" -- just a new name for "returning an error code", if you will -- at the point where the error occurred, and then it would automagically trickle back up the call stack to the one most suitable point you wanted to deal with this particular kind of error.

The only really significant difference from the old "return an error code" system -- and thus the only reason to change systems in the first place -- was that this would happen without you having to explicitly screw around with the code of the intervening "layers" (to borrow your terminology) every time you change something to throw a new kind of error several layers removed from where you're handling that kind of error.

Now, introducing the "checked exception" in Java, Sun managed to... Undo the whole idea, AFAICS. It's like, first somebody goes all "Hey, let's invent something we'll call an 'exception', so errors can occur in one place and be caught in another, without having to constantly make sure to transfer received error codes back up the call stack through several layers!" And then Gosling goes, "Yeah, great idea! Only, to make it even better, we'll make sure every time someone changes their error handling, they will have to change the code of each intervening layer!" Like, HEL-LOO... Anyone at home behind that beard???


, and that for developers to ignore them (or treat them improperly) is to make for bad development. So, it's not a problem with checked exceptions, themselves, as it is a problem with training developers to think differently about how they code.
No, (for once) you're wrong to blame the developers (for this particular problem). It is unreasonable to expect them -- us -- to think sensibly about how to handle "checked exceptions", because there IS no sensible way to think about such a self-contradictory concept.


   [link|mailto:MyUserId@MyISP.CountryCode|Christian R. Conrad]
(I live in Finland, and my e-mail in-box is at the Saunalahti company.)
You know you're doing good work when you get flamed by an idiot. -- [link|http://www.theregister.co.uk/content/35/34218.html|Andrew Wittbrodt]
New ICLRPD (new thread)
Created as new thread #143877 titled [link|/forums/render/content/show?contentid=143877|ICLRPD]
===

Implicitly condoning stupidity since 2001.
New Re: But that would (i.e, *does*) defeat the whole purpose!
Though I agree that "exceptions" were meant to move away from return codes by "centralizing" the error handling, I disagree with your definition of "centralize."

Checked exceptions merely provide compile-time checks on error handling. They are neither good nor bad, but act as a tool by developers. They force developers to *think* about exceptions by forcing them to make the compiler happy.

Centralization requires a definition of what central is (that is, define the point). If centralization means a particular "layer" within code, so be it. If it means the main thread of execution, fine. For GUI applications, it may mean pushing the original exception up the stack far enough to display to the user. In a batch system, where there is no user, that central location may be completely different. It's a question of where (locality).

I think a better argument against checked exceptions is how they provide a capability that is not easily handled by unchecked exceptions. Again, it comes down to providing a compile-time check. I understand that many here prefer run-time checks rather than compile-time ones. I think that more a taste, and I have no issue with that. My only real argument is that checked exceptions work well in certain circumstances and that I've found them useful.

However, I heartily agree that they have been misused, especially in the core JDK libraries. This has given them a bad name. It's a question of well designed use.

Dan
New Sorry, either I don't get your meaning, or you didn't mine.
Dan S continues the discussion:
Though I agree that "exceptions" were meant to move away from return codes by "centralizing" the error handling, I disagree with your definition of "centralize."
How can you do that, when I didn't give one?


Checked exceptions merely provide compile-time checks on error handling.
There's checks and there's checks... Checked exceptions don't "merely" provide "compile-time checks on error handling", they provide paranoid, self-contradictory, concept-defeating compile-time checks on *EVERY STEP BETWEEN* error and handling.


They are neither good nor bad, but act as a tool by developers.
No, they are bad, because they act as _a hindrance_ to developers.

I mean, heck, this is a _fact_, attested to by heaps and reams of evidence all over the Net. (Sure, you may want to call that evidence "anecdotal"... But isn't all evidence "anecdotal", in a way? Doesn't it become a little less "anecdotal" [as in "of no consequence"], when it includes *your own* observations? It sure looks like more of a fact than do the misguided *intentions* of Java's designers, at least.)


They force developers to *think* about exceptions by forcing them to make the compiler happy.
No, they obviously don't -- what they *really* do is: They force developers to *catch* a lot of exceptions to make the compiler happy, which leads to UN-thinkingly catching (often, just to "swallow" and forget) TOO many of them.

You might want to blame that on the developers, but:

A) It's a perfectly natural "path of least resistance" reaction to an overly restrictive system,

B) this reaction seems blindingy obvious (at least to me, but I have to admit I wasn't there when Java was designed), and as such should have been easily predictable,

C) so in total, they DON'T lead to what you claim they were intended to lead to, but rather the opposite.

Ergo, they don't work.

(Yeah, it's really that simple: They just don't work, in the real world outside Gosling's beard.)


Centralization requires a definition of what central is (that is, define the point). If centralization means a particular "layer" within code, so be it. If it means the main thread of execution, fine. For GUI applications, it may mean pushing the original exception up the stack far enough to display to the user. In a batch system, where there is no user, that central location may be completely different. It's a question of where (locality).
No, it is NOT "a question of where (locality)", and no, 'centralization' in and of itself does certainly NOT require a definition of "what central is".

Centralization is a *concept*, an *idea* -- exactly *what* point ("locality") you center on, is implementation-dependent and doesn't matter for the concept per se. That is, exceptions were supposed to let you have your error handling at some *arbitrary* central point *of your choice*.

The point (of my argument, not the central one we talked about above) is, exceptions were supposed to let you handle your errors at this arbitrary central point of your choice, WITHOUT having to touch all OTHER areas of code in between where the error occurred and where it's handled.

Once you defeat that, you've *defeated the whole idea* of exceptions, and can just as well go back to return codes -- because you've just re-created them, only bloated by several orders of magnitude.

How can you *not* see this?!?

Or, if you still want to claim there's a difference: Could you explain *exactly* what it is, "as if to a four-year-old"?


I think a better argument against checked exceptions is how they provide a capability that is not easily handled by unchecked exceptions.
Huh?

If they actually provided any capability that other systems don't, wouldn't that be an argument FOR them?


Again, it comes down to providing a compile-time check. I understand that many here prefer run-time checks rather than compile-time ones. I think that more a taste, and I have no issue with that.
Heh -- yeah, I'm well known here for my anarcho-libertarian preference for run-time checks and aversion to compile-time ones... Sorry, but more seriously, *that* kind of compile-time checks isn't the only one there is.


My only real argument is that checked exceptions work well in certain circumstances and that I've found them useful.
Hmm, yeah, well... Hard to argue with experience. (If you're *sure* you haven't somehow deceived yourself into thinking so? :-)


However, I heartily agree that they have been misused, especially in the core JDK libraries. This has given them a bad name. It's a question of well designed use.
I think "well designed use" of a mis-feature is a contradiction in terms.


   [link|mailto:MyUserId@MyISP.CountryCode|Christian R. Conrad]
(I live in Finland, and my e-mail in-box is at the Saunalahti company.)
You know you're doing good work when you get flamed by an idiot. -- [link|http://www.theregister.co.uk/content/35/34218.html|Andrew Wittbrodt]
New What ends up happening ...
is that you have reams of code catching exceptions, wrapping them in some new exception and throwing them. What value have you added by wrapping the original exception 10 times? Take a typical example. Your low level data layer fails getting data from the database for some reason (e.g. because the database is down). In most cases there is nothing that you can really do with this exception except log the error and present an error message to the user. What value is there in making all the intermediate layers catch the exception wrap it in a different exception and throw the new exception? What value have you added? The bottom line is that the topmost gui layer should catch the exception and present the error message whether or not you wrapped the exception 10 times or not.
New Re: What ends up happening ...
I think 10 times is a little excessive. And I think the database access (specifically SQLException) is also a poor example, as it's debatable whether it should have been a checked exception in the first place.

Dan
New Re: What ends up happening ...
[i]I think the database access (specifically SQLException) is also a poor example, as it's debatable whether it should have been a checked exception in the first place.[/i]

OK but its debateable whether any exception should be a checked exception. For instance, InputStream - a fully abstract class - insists than any method may throw an IOException which must be caught (its checked). Yet there are instances of InputStream that do not throw this exception - yet the programmer is still burdened with writing code to handle exceptions that will not be thrown. This is a fundamental problem with static typing and hard wired method signatures.

InputStream in = new StringBufferInputStream(buffer);

int c = -1;
try { c = in.read(); } catch(IOException ex) {} // won't really throw

Of course, you can't exactly know that in is going to reference something that won't throw.

My biggest complaint though is that checked exceptions leak concerns of implementation into the interface. This results in very brittle systems.


The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
New You didn't answer the question ...
What value is there in wrapping exceptions?

10 was obviously an exaggeration.

What do you think should have been an unchecked exception?
New Re: You didn't answer the question ...
Wrapping exception is used to create a facade to the next layer. So, since SQL exceptions are checked, I can do one of two things: I can wrap them and rethrow them as application-specific checked exceptions, or I can rethrow them as unchecked exceptions. For SQL exceptions, I've seen both. Personally, I usually wrap them in checked exceptions because I like to associate a prettier error message with them as close to where it happens (I have more contextual information at that point). Then, I have a simple application-specific checked exception that the higher layer (say the presentation layer) can deal with in a generic, simple fashion (in some cases, the higher layer may not even need to know anything about the exception because it contains enough information for display purposes, but that's dependent upon the application type and how it's designed).

I approach unchecked exceptions in this way: if it's a programmer's error (i.e. a null pointer exception or something like that), an error (i.e. out of memory), or something that can't be handled and dealt with at a lower level (because the contextual info isn't helpful, or it doesn't make sense to), then using unchecked exceptions works well. However, if it's a application exception, such as bad input from the user, database going down (and this one can go either way...it depends upon the interface to the user), etc. then checked exceptions are nice because they can usually be handled nicely by the upper layer.

Hope that answers your question.

Dan
New A number of comments
1. in any given layer the exception can occur far down the call stack. Especially if you write short methods you may be far down the call stack when you catch and wrap an exception. This means that every method above you in the call stack needs to do something with the exception, probably just throw it, clearly a waste.
2. If each layer only throws 1 exception you lose information. The UI may want to display different pages depending on the exception. For example, if you receive a licensing exception the UI may want to display a licensing page, while a validation exception may redisplay the form. By wrapping the exceptions in a general exception youy make it hard for the client to figure out what really went wrong. The client then has to go and look at the wrapped exception and get the cause.
3. Many times you have a number of layers and they just wrap the exception without adding any new information.
New We already discussed this
[link|http://z.iwethey.org/forums/render/content/show?contentid=118548|http://z.iwethey.org...?contentid=118548]

In particular see my response at [link|http://z.iwethey.org/forums/render/content/show?contentid=118648|http://z.iwethey.org...?contentid=118648] which hopefully will cause you to reconsider your view that the issue of their predictable misuse can be pre-emptively ignored.

Cheers,
Ben
"good ideas and bad code build communities, the other three combinations do not"
- [link|http://archives.real-time.com/pipermail/cocoon-devel/2000-October/003023.html|Stefano Mazzocchi]
New Re: We already discussed this
Unfortunately, it does not. The assumption that just because something is misused, that it is somehow intrinsically (sp?) wrong is not a strong enough argument. That does not mean, however, that misuse doesn't point in that direction. It's just not enough to prove. So, I agree that it requires a closer analysis, but I don't agree that it necessarily provides proof.
New Blame the tool
Not the craftsman. Really.

If a tool's design results in the majority of the tools users subverting the tool to accomplish their task, then the tool needs redesign.

Don Norman says it better than I [link|http://www.pcd-innovations.com/norman.html|http://www.pcd-innov...s.com/norman.html]

"Blame and train does not solve the problem."

and here: [link|http://www.typotheque.com/articles/don_norman.html|http://www.typothequ...s/don_norman.html]

Humans are fallible. Learn that. Cherish that. It is a fact of life. We people are creative, exciting, adventurous, imaginative, artistic, emotional, musical. And fallible.

Design for people as they are, not as you would have them be. Design for inefficient users. Design for fallible users. Design for creative, imaginative people who will do things with your design that you never dreamed of, things both good and horrid. Design for people who are tired and stressed, cranky and irritable, sloppy and inattentive. In other words, design for real people.

---------

IOW, the design of Java's checked exceptions doesn't work because it demands too much of the developer and ultimately produces brittle systems. The convenient expedient workaround is to simply swallow the exception - and that's what happens most of the time.


The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
New You're right, that is unfortunate
My objection was not to the statement that the fact that something got misused is an indictment of that thing. It was instead to your statement that, I've not heard one respectable reason against the *concept* of checked exceptions (their misuse doesn't count as one).

This proactively discounts discussing the fact that they will routinely get misused for very predictable reasons. Since that is my issue with checked exceptions, from my point of view you have started the conversation with, I've never heard a good reason for disliking them and I won't hear yours either!

For a good counter-balance I'd strongly recommend reading (or re-reading if you have read it) [link|http://www.amazon.com/exec/obidos/tg/detail/-/0385267746/002-0596161-0040802?v=glance|The Design of Everyday Things]. Good design does not lie in making something that theoretically can work well if it is used properly. It lies in making something that actually does work well when used by real humans in the real world.

Cheers,
Ben
"good ideas and bad code build communities, the other three combinations do not"
- [link|http://archives.real-time.com/pipermail/cocoon-devel/2000-October/003023.html|Stefano Mazzocchi]
New Re: You're right, that is unfortunate
I'm certainly interested in hearing reasons why checked exceptions are bad. The problem is, most of them are because of its misuse. I agree that they get misused. However, lots of things get misused, but are still helpful and useful in some situations.

Is Perl a *bad* language because it gets misused (and I mean misused in the sense that it's really easy to code unmaintainable scripts, etc.)? Is inheritance *bad* because every newbie to OO takes it *way* too far and ends up with many extra layers that aren't necessary? Could they all have been designed better so that they wouldn't have been misused so much? Maybe. But, as has been pointed out, we're all fallable, so no language will prevent misuse, regardless of how well it's designed.

As for the book, yes, I've read it (a couple of times). And I agree with it (though he wasn't overly organized in the development of his point, though I still thoroughly enjoyed it). However, I think we're so far away from a "well-designed" language as to be miles from what he would recommend. I don't know of any language that comes close to being intuitive for development (and that includes Java, Smalltalk, Perl, C, or any others). At least not to what I would consider his criteria.

But, we deal with what we can with what we have (until someone pays us enough money to come up with something better). I'm certainly not going to state that Java is the best language (using any criteria), but it has some features that are an improvement over other languages (some, not all) that are helpful for some developers.

Dan
New You have to balance benefit/cost
Do you use goto extensively? Why or why not?

Yet the fact is that goto is only harmful when misused. As Knuth famously pointed out in a paper devoted to the subject, goto has legitimate uses within structured programming. (At least in languages like C which do not have labelled loop control.) Why then do people generally discourage its use so strongly?

You use the example of Perl being bad. It is a truism that it is really easy to code unmaintainable code in any language. It is obvious that Perl has a poor reputation in this way. However Perl also has an excellent reputation for resulting in good productivity. And Perl certainly has been an effective tool for a lot of people. It has costs and benefits. Sometimes it is worthwhile, and sometimes it isn't. Choose wisely for your situation.

You use the example of inheritance being bad. The same thing holds. There is a skill to design, and people only learn what the problems are by making mistakes. It is obvious that there are benefits and costs of inheritance and make a case for when it is appropriate.

So far I am speaking in truisms. So it is a truism that the same must hold for checked exceptions. As I pointed out in [link|http://z.iwethey.org/forums/render/content/show?contentid=118648|http://z.iwethey.org...?contentid=118648], the benefit as I understand it to checked exceptions is that it makes it easier to prove that you have accounted for every possible exceptional case somehow. If that is your primary goal, and the goal of your whole team, then I'll buy that checked exceptions could be worthwhile.

But checked exceptions are in the (very long) list of technologies that require extra work from users to solve a problem that most of them don't care about. Every last one of those technologies - checked exceptions included - runs into constant problems as users set out to satisfy their goals and therefore shortcut on the extra work in the most convenient way possible. Which, in the case of checked exceptions, is going to mean that errors get swallowed from time to time.

The vast majority of programmers need to make some pragmatic tradeoff between things like bugs, development speed, the ability to make random changes later, etc. Statically proving at compile time that every i is dotted and t is crossed in all possible exceptional circumstances is rarely anywhere near a top priority. It certainly is lower than guaranteeing that code does what it is supposed to do in response to different kinds of user input.

If you are, or you work with, programmers who do not prioritize what checked exceptions can do for you, then they are not going to be worthwhile. More than not just being worthwhile, but people working around checked exceptions to satisfy their personal goals is likely to lead to poorer satisfaction of my goals. I think that this clearly covers most of us.

So, except for a vanishingly small fraction of programmers, I do not see that checked exceptions are worthwhile.

Cheers,
Ben
"good ideas and bad code build communities, the other three combinations do not"
- [link|http://archives.real-time.com/pipermail/cocoon-devel/2000-October/003023.html|Stefano Mazzocchi]
New s/Knuth/Dijkstra/
[link|http://www.acm.org/classics/oct95/|Go To Statement Considered Harmful].
Alex

Necessity is the plea for every infringement of human freedom ... the argument of tyrants ... the creed of slaves. -- William Pitt, addressing the British House of Commons (1783)
New I had it right the first time
Specifically I was thinking of Structured Programming with go to Statements, which is not available consistently on the web, but you can sometimes find a copy through Google. (Which doesn't last because it is a copyright violation.)

Cheers,
Ben
"good ideas and bad code build communities, the other three combinations do not"
- [link|http://archives.real-time.com/pipermail/cocoon-devel/2000-October/003023.html|Stefano Mazzocchi]
New I stand corrected then.
[link|http://www.stevemcconnell.com/ccgoto.htm|The Argument for gotos].
Alex

Necessity is the plea for every infringement of human freedom ... the argument of tyrants ... the creed of slaves. -- William Pitt, addressing the British House of Commons (1783)
New Re: Because checked exceptions are STOOPID!
Since there are several separate threads (that is, responses to response) within this, it's going to get tedious responded to each and every one of them separately, so, if it's okay with everyone, I'll try to pull my responses down this direction to try to keep things a little clearer and cleaner...

First of all...I have no issue with agreeing to disagree. My experience has been my own, and I've found checked exceptions helpful. I've also seen them misused, etc. I think that they can aid developers when used appropriately. And yes, they become a pain when not used appropriately. Part of my perspective is probably tainted by years of experience working with Java (I used to do C/C++, but it's been a while).

Having said that, let me see if I can restate and handle most of the objections as best I can (and I fully admit to being unable to clearly express my opinion, but I'll do my best).

Interfaces: I actually think that using checked exceptions in interfaces is a good thing (within reason, of course). Why? Because I perceive an interface (a Java interface) to dictate a particular role for a class (that implements it). The interface defines certain signatures, which have a return type, method name, and parameters. I think checked exception make a welcome addition to it (that doesn't mean that all interfaces should have checked exceptions defined...only if it makes sense). I don't think that it makes the interface fragile. In fact, as crazy as it sounds (and I'm sure it sounds crazy), I have no problem with an interface defining an exception when some of the implementations of it may not actually thrown the exception. Why? Because that's part of the signature, and as a user (from an API perspective) of that interface (not as the implementor), I make certain assumptions about the method (including any checked exceptions). It's more information (even if it's the wrong info). It tells me that I should beware of the particular method, as it *may* throw that exception (even if a particular implementation will never do so). I realize that that flies in the face of what many of you consider good, but my reasoning for it is one of trust and information. I want to know what I'm getting into with a particular interface, and I trust that the designer/developer of it has written it such that I, as the user (from an API perspective), view it as it was meant to be (an method returning a particular value, taking certain parameters, and potentially throwing certain exceptions).

Misuse: though I agree that they get misused, I don't think it's appropriate to discount it as much as it's necesary to educate. There are many language tools that get missused, such as inheritance, etc. I think any developer who freely ignores return code is the same one who will freely ignore checked exceptions, and who is the same one who will not use unchecked exceptions appropriately, either. In that case, checked exceptions are no more valuable than return codes, except for one difference: in order to ignore checked exceptions, the developer has had to go out of their way to ignore them (they had to either rethrow it or catch and ignore). In that way, they are a little better.

Back in my C/C++ days, it was common to see code like this:

funcBar(...)
{
doA(...)
doB(...)
doC(...)

return foo;
}

with each doX() method returning something (zero if successful). With exceptions (checked or unchecked), the assumption is that those methods will perform just fine (assumed success) unless an exception is thrown, in which case, a catch clause somewhere up the stack will stop and do something interesting.

The problem is the checked exception tends to make the developer deal with an unsuccessful call too soon. In some scenarios, this becomes a pain, because the exception should be dealt with at a high enough place in the stack to be interesting. For those situations, it makes sense to wrap it in an unchecked exception and rethrow. However, in other situations, it makes sense to deal with the exception sooner, if for no other reason that to put a pretty error on the exception at the point where enough context is known to do so. The real question is whether it's appropriate to *force* someone to deal with that exception sooner, rather than later.

So, ultimately, I think it's a question of perspective. From a user of an API's perspective, it's common to complain about checked exceptions. From a designer of an API, it's common to want to dictate as much as possible, in order to give as much information to the user as possible. My perspective is, it's easier to produce safer code when the compiler helps the designer to dictate the way in which an API is used. Hence, the layered approach lends itself to checked exceptions because each layer (and I'm talking high-level layers here, not individual methods in a stack trace) can be independent from the next.

Again, I think it's a question of a tool to use to help. Unfortunately, it's been misused enough to cause a backlash. And in some cases, rightly so, since many libraries have not designed their exception handling well.

Dan
New Hmm...
Rather convincingly reasoned, that; I may have to reconsider my position somewhat.

(Don't expect a complete conversion, though! :-)


   [link|mailto:MyUserId@MyISP.CountryCode|Christian R. Conrad]
(I live in Finland, and my e-mail in-box is at the Saunalahti company.)
You know you're doing good work when you get flamed by an idiot. -- [link|http://www.theregister.co.uk/content/35/34218.html|Andrew Wittbrodt]
New One phrase says it all.
"It's more information (even if it's the wrong info)."

I don't think the ability to present more info compensates for the fact that the information can be wrong, there is no way to make it right, and you are forced to act on that information (wrongly).

Could you offer an example of _correct_ use of checked exceptions? So far, people have been agreeing on how bad each offered example was.
--

The number of the beast - vi vi vi
--[link|http://c2.com/cgi/wiki?QuotesOnComputers|Delexa Jones]
New Caught my eye too
I seem to recall that the technical term for valueless information is NOISE!


The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
New Re: One phrase says it all.
As I was writing that phrase about more information being good, regardless of it being wrong kind of struck me as a really poor way of explaining things. On the surface, I would completely agree with you.

It makes some sense that, given an interface (with defined checked exceptions) with a particular implementation not throwing said exceptions, that the interface is considered "wrong" because an implementation doesn't actually implement it (that is, it doesn't have the possibility of throwing an exception, so it could be said that the interface isn't truly implemented properly....it's "wrong").

However, that's not how I looked at it (though that appears to be how I said it, which is obviously my fault). The way I looked at it was that the interface defines a particular set of signatures (for our purposes, one is enough). For that particular signature, it defines three basic things: the return type, the parameters, and a checked exception (I know, there are other things in there, such as the ordering and types of parameters, etc...just trying to keep things simple). The checked exception means (as I look at it) that the method *may* throw an exception of that type. That means that it may not. In fact, I *hope* that it doesn't, but I code such that it might.

Because I trust the signature (the compiler says I can), I assume that it's possible. The checked exception gives me additional information in that it's a *hint* that a particular exception *may* (and *can*) be thrown. It doesn't state that it *must* or that it *will* under any given circumstances. In that case, it's additional information that isn't necessarily *wrong* if a particular implementation doesn't actually throw the said exception. It comes back to perception, I guess.

If we change the example so that it was an unchecked exception, instead, would that change anything? First off, I would *hope* and assume that the interface was well enough documented that it would indicate that an unchecked exception might be thrown under certain situations (something like: this method may throw this exception....). If not, then I would not have a lot of trust in that interface as I'd probably get exceptions thrown and not know that I was to catch them (this isn't a question of *where*, but the need to know that it can so that I can make the decision as to where).

Given that it's well documented, what about an implementation of that interface that didn't throw the exception? Depending upon how I use that interface, I may not know that a particular implementation doesn't throw the exception? Why? Because the construction of the implementation may be hidden from me, so I may not even know what class I'm actually using (that's the whole point of using an interface, after all). So, I would handle the situation identically, regardless of whether there was a checked or unchecked exception (granted that there may be slight differences in the syntax, since I have more flexibility as to where I deal with the unchecked exception, but I also have better inherent documentation with the checked one...it's a trade-off, to a certain extent).

As for a good example of a checked exception...

Since most of my current experience is with web-based apps, I'll use a fairly simple example: a Struts-based web app.

I create a business object layer that handles the business logic (and, somewhere in there, persistence). That layer defines some interfaces and concrete classes that the presentation layer interfaces with. Where appropriate, the business layer throws a standard application exception (with possibly a couple sub-classes if necessary). In the presentation layer (say, the struts action class), calls are made into the business layer. Since I, as the business layer writer, provide a single exception layer to the presentation layer, it can easily have code that does something like this:

try
{
...get data from user or whatever.
callBusinessLayerA(...);
callBusinessLayerB(...);
...use data from business layer to setup view or whatever.
}
catch ( ApplicationException e )
{
..set up error messages to display error from business layer...
}

Obviously, I'm leaving out lots of details, but the idea is that the presentation layer only deals with one (or only a very small number) application layer.

Of course, this can just as easily be done using unchecked exceptions. The difference is one of safety. As the writer of the business layer, I'm forcing the presentation layer developer to deal with my exceptions. If he merely ignores them (nothing in the catch), then hopefully, that'll get caught in testing or code review. In fact, it's fairly easy to write up a tool to automatically find those kinds of bugs (there are probably tools out there that do it, in fact).

I realize that it's a fairly simple example, but the idea of layering the exceptions simplifies things considerably. When dealing with junior to mid-level developers, I like the additional safety (try working at places like EDS or Accenture where the developers are not trained or taught...having extra checks like this are really helpful).

Dan
New I remain unconvinced
And its entirely based on my experience.

The fact is that the vast majority of busy developers don't have or don't take the time to follow your wrapping strategy. Its much too time inefficient and the payoff isn't really there (practically nobody on the user side of the system sees the benefit).

(There is a whole other rant I'm holding back on the excessive "wrapping" of layers - ie JDBC is already an abstraction layer - don't hide it).

Which tells me that its a failed "solution". I myself have become annoyed during a time crunch at changing the implementation of a method only to have a new checked exception appear in the implementation. The need to suddenly change the method signatures of every method on the call stack of said method (or take time out and write a wrapper exception class) annoyed me to the point that I simply swallowed it. Sue me I was on a time crunch. I've done this more than once BTW.

More importantly, this is rampant in code I see elsewhere. Which tells me that we haven't really solved the problem. More importantly, were these exceptions not checked and the burden of changing all the method signatures not there, a catch clause would likely simply be put at a reasonably sensible default location (like at the event polling/web request handling bottleneck) and its resolution could be incrementally improved based on the kinds of errors found in testing.





The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
New A Further Question on the Code Example
Thanks Dan for your well reasoned discussion. I'm not sure I agree with everything you said, but I'm going to take some time to put my thoughts in order on the topic.

However, I would like to explore the example code a bit. I started this thread with the intention of talking about catching explicit exceptions contrasted with catching general exceptions. Checked vs Unchecked, although related, is a bit of a side track.

Consider code snippet you shared...

try\n{\n...get data from user or whatever.\ncallBusinessLayerA(...);\ncallBusinessLayerB(...);\n...use data from business layer to setup view or whatever.\n}\ncatch ( ApplicationException e )\n{\n..set up error messages to display error from business layer...\n}
I assume the purpose of the catch clause is to catch the non-fatal failure modes of the try block and to report those failures in user in some fashion (e.g. log them, or an error dialog).

If that is the case, why wouldn't you catch Exceptions rather than ApplicationException. After all, failing because of a null pointer is just as much of a failure as anything else and I would expect all failures to be handled consistently.

I understand catching a specific exception in order to provide specific logic for a certain kind of failure, but ApplicationException seems to be too general for that purpose.

Thanks for the time and effort you have spent on this discussion.
--
-- Jim Weirich jweirich@one.net [link|http://onestepback.org|http://onestepback.org]
---------------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
Expand Edited by JimWeirich March 2, 2004, 01:20:53 PM EST
New Re: A Further Question on the Code Example
Well, I appologize for the side track. To be honest, part of the reason for even bringing up the isue was that there has been a lot of debate about it, but most of the complaints against were based upon developers misusing it, which I thought wasn't necessarily a good reason for complaint (more of an educational opportunity). I don't really care to convince anyone, as everyone's experience is a little different, and situational uses tend to be unprovable and uninteresting (from a pure "good" versus "bad" perspective).

But, to answer your real question, let me complete that example with an explanation. The reason why I wouldn't catch a more general exception (java.lang.Exception) is that it's caught somewhere else (and not by my code). I think there is a difference between the two, even to the user.

First, I may not necessarily need to do anything other than display a pretty message to the user for an application exception (now, I'm going to go off the deep end here and get myself into trouble, but it's even interesting, to me, to have validation checks throw exceptions that get displayed to the user through that method). It may not even log (in some cases, it should...as usual, depending). And there's certainly no need for a full stack trace in the log.

For the more general exception (meaning, an unchecked exception or such, like java.lang.Exception), the container (in the example, that would be the web container) would ultimately catch the exception, log to a specific error log, dump the stack trace, etc. It would also display a different kind of error message. Why? First, because it really is a different kind of error. If it's a null pointer exception, there's no pretty way to tell the user that they're staring at a bug. Instead, you display a big general "Yikes!" message and send the user somewhere, as opposed to redisplaying the same page with a couple of error messages or something. I know this may sound stupid, but you want the user to complain about those big ones so that they will get fixed (this is the old issue of: I don't have time to fix it, but if the user screams loud enough, my manager will make the time).

Anyway, if you, ultimately, consider them to be the same basic thing, then, yes, you can catch the more general exception and the checked exceptions will probably get in the way.

Dan
New Bad for class libraries?
Seems that all the counterexamples come from shared class libraries and involve inheritance and implementing of interfaces. Your example is from the code fully under your control and (I am speculating) does not use deep inheritance/implementation hierarchy.

Could that be the distinction between correct and incorrect use of checked exception? And, if so, don't checked exception make code less easy to reuse and refactor?
--

The number of the beast - vi vi vi
--[link|http://c2.com/cgi/wiki?QuotesOnComputers|Delexa Jones]
     Exception Handling Policy - (JimWeirich) - (48)
         Possibly it depends on what level of code you are writing... - (Simon_Jester) - (38)
             Ditto. - (admin) - (37)
                 Because checked exceptions are STOOPID! - (tuberculosis) - (35)
                     One reason I like Spring Framework - (admin) - (1)
                         Absolutely - (bluke)
                     Re: Because checked exceptions are STOOPID! - (dshellman) - (23)
                         One respectable reason - (admin) - (13)
                             Re: One respectable reason - (dshellman) - (12)
                                 The problem with Java model is that I cannot - (Arkadiy) - (1)
                                     Re: The problem with Java model is that I cannot - (dshellman)
                                 But that would (i.e, *does*) defeat the whole purpose! - (CRConrad) - (3)
                                     ICLRPD (new thread) - (drewk)
                                     Re: But that would (i.e, *does*) defeat the whole purpose! - (dshellman) - (1)
                                         Sorry, either I don't get your meaning, or you didn't mine. - (CRConrad)
                                 What ends up happening ... - (bluke) - (5)
                                     Re: What ends up happening ... - (dshellman) - (4)
                                         Re: What ends up happening ... - (tuberculosis)
                                         You didn't answer the question ... - (bluke) - (2)
                                             Re: You didn't answer the question ... - (dshellman) - (1)
                                                 A number of comments - (bluke)
                         We already discussed this - (ben_tilly) - (8)
                             Re: We already discussed this - (dshellman) - (7)
                                 Blame the tool - (tuberculosis)
                                 You're right, that is unfortunate - (ben_tilly) - (5)
                                     Re: You're right, that is unfortunate - (dshellman) - (4)
                                         You have to balance benefit/cost - (ben_tilly) - (3)
                                             s/Knuth/Dijkstra/ - (a6l6e6x) - (2)
                                                 I had it right the first time - (ben_tilly) - (1)
                                                     I stand corrected then. - (a6l6e6x)
                     Re: Because checked exceptions are STOOPID! - (dshellman) - (8)
                         Hmm... - (CRConrad)
                         One phrase says it all. - (Arkadiy) - (6)
                             Caught my eye too - (tuberculosis)
                             Re: One phrase says it all. - (dshellman) - (4)
                                 I remain unconvinced - (tuberculosis)
                                 A Further Question on the Code Example - (JimWeirich) - (1)
                                     Re: A Further Question on the Code Example - (dshellman)
                                 Bad for class libraries? - (Arkadiy)
                 Re: Ditto. - (JimWeirich)
         I meant Exception the class - (bluke) - (7)
             Don't catch null pointer exceptions? - (JimWeirich) - (6)
                 In development yes - (bluke) - (5)
                     Re: In development yes - (JimWeirich) - (4)
                         Agreed - (bluke) - (3)
                             So wouldn't the remedy be... - (CRConrad) - (2)
                                 cf. Spring Framework :-) -NT - (admin)
                                 I agree ... - (bluke)
         Another reason to catch specifics - (jb4)

Well, yes, because everyone knows that having an Italian travertine fireplace in just one color is gauche.
357 ms