Voting for Checked Exceptions
Yet another hideous idea from the closures camp: removing checked exceptions from the language. Now they want to remove one of the features from Java that actually works to support their pet obfuscation.
According to Neal Gafter:
We did a Google search to see how many people have written in support of checked exceptions and how many people don’t like them. The discussion seems to be lopsided against checked exceptions, but on the other hand that may be due to the fact that checked exceptions are the status quo.
For his next Google search, let me just say, I like checked exceptions and I want to keep them. The people who object to checked exceptions mostly seem not to know the difference between checked and unchecked. Most importantly, they seem not to know when to use checked exceptions and when to use unchecked exceptions. A few libraries such as the Java USB API even get this exactly backwards. And I will admit, if you don’t know this crucial piece of information, then checked exceptions seem ugly and confusing.
However, if you do understand the difference Java’s exception handling is the single best error handling and reporting mechanism ever built into a programming language. It is a strength of the language, not a weakness. To date, I don’t think any other language has come close to matching Java’s robust exception handling, and resistance to distinguishing checked from unchecked exceptions is the reason why.
I don’t have time this morning to explain the exact difference between checked and unchecked exceptions, so just go read section 8 of Effective Java, particularly items 40 and 41. In brief, checked exceptions are for unpredictable environmental conditions such as I/O errors and XML well-formedness violations while unchecked exceptions are for program failures that should be caught during testing, such as array index out of bounds or null pointers. A checked exception usually cannot be avoided by changing your code while an unchecked exception usually can be. That is, an unchecked exception normally indicates a bug in your program, and a checked exception doesn’t. That’s why we have to catch or declare checked exceptions and not runtime exceptions. A runtime exception will usually occur every time the code takes a particular path, whereas a checked exception may occur some times when a program runs through a path and not others, because checked exceptions depend on environmental conditions outside the program’s direct control. Therefore a problem that causes a runtime exception should be detected and fixed during testing, whereas a checked exception may well only appear in a customer environment. Anybody who doesn’t understand this has no business pontificating about exception handling in Java.
But please: can we take the idea of removing checked exceptions from the language off the table? They are far more important to developing reliable, comprehensible, robust code than closures ever could be. Closures are just syntax sugar that don’t let you do anything you can’t do in other ways already. Checked exceptions are a much more core feature that cannot be replaced with a little syntax sugar.
May 30th, 2007 at 7:46 am
Closures are just syntactic sugar? Since when? I suppose next they’ll be claiming that anonymous functions are syntactic sugar. Oh wait.
May 30th, 2007 at 7:47 am
Elliotte said, “However, if you do understand the difference Java’s exception handling is the single best error handling and reporting mechanism ever built into a programming language?”
Ha! Ha! Had a nice laugh this morning. Do you like writing code with a lot of try…catch blocks? Where can I get some more of that Java Koolaid, Elliotte?
How come no other language has checked exceptions (as far as I know) and yet so many of these languages manage to be quite successful? If checked exceptions are so great, how come other language users are not clamouring for checked exceptions in their language?
Isn’t it you who has is confused about the usage of checked and unchecked exceptions? If I recall correctly, Rod Johnson (he of the Spring framework) says that checked exceptions should be used for cases that the application knows how to handle. Presumably some code up the call stack will know what to do with the specific checked exception thrown. When the application has no way of knowing what to do with an exception (database unavailable, Web Service not available, etc.) then an unchecked Runtime exception can be thrown.
Since you seem not to understand the difference between checked and unchecked exceptions, (in your own words) what business do you have pontificating about Java? Please stick to writing books and selling to the hoi polloi, not the cognoscenti.
May 30th, 2007 at 8:10 am
I absolutely disagree. Checked Exceptions are not helpful at all. On the contrary. Take a close look at C# and the reasoning of Anders Heijlsberg, why Checked Exception were the part that they did not steal from Java. Among other reasons they did not do it, because Checked Exceptions become part of the methods signature and they did not want to statically refer to the implementation details — which makes sense to me. If your claim were right, that Checked Exceptions provide a benefit that high level programming languages are lacking, then why don’t we have a breakdown of all those systems that do not have them? In addition, Checked Exceptions force the developer to deal with problems that in most cases are a bug — contrary to what you claim. Take JDBC. This API is riddled with Checked Exceptions that really indicate serious trouble rather than, “hey, we can deal with this”. If I cannot open the connection to the application’s designated database for whatever reason then that’s really something that the application cannot recover from. So, Neal has my vote. And good riddance.
May 30th, 2007 at 9:13 am
Ravi …
I think you are a bit confused. My application *should* know how to handle certain predictable but *exceptional* cases, such as when I need to access a database which isn’t available.
May 30th, 2007 at 9:35 am
When a database is down, the most meaningful thing that can be done is to inform the user and exit the application (Unless an alternative data source is available, or if the data from the database is not really required.)
If this is written as a checked exception, then all the way up the call stack one must throw this exception in the method declaration, leading to code bloat; or one must handle it immediately and then exit.
Throwing a RuntimeException in this case makes sense because any caller up the stack can handle this if it knows what to do; or else simply pass it back up the stack until one quits the application. Checked exception here gives no benefit except to the consultant who write bloated code or gets paid by the number of lines of code/time spent.
So, pjc, I beg to disagree with you on this point.
In the Java community the debate on checked vs unchecked exceptions is still undecided. More to the point, by making such assertions as “Anybody who doesn’t understand this has no business pontificating about exception handling in Java” on an ongoing topic, Elliotte invites others to reply in kind. Which is what I did.
I do like strong views even when they disagree with mine, especially if they disagree with mine. But I will also not refuse a challenge as that thrown by ERH who expressed his views strongly.
May 30th, 2007 at 10:22 am
Well, I for one agree with ERH. He describes the distinction correctly.
Checked exceptions also tell you when you may need to do some cleanup before continuing. If really think you know all of the cleanup is completed (something no piece of code can claim for the code that calls it, but I digress) then you can wrap the checked exception in an unchecked exception. The key is that the programmer was alerted to the fact that ’something bad can happen here’ by the compiler and has the opportunity to address it. IDE’s can help you track where checked exceptions come from. They can’t do that with unchecked exceptions. Knowing about the exception also give you the opportunity to add more information to it before it is thrown up the chain. For instance, what is the id of the object that was just involved in the failed transaction? If that information gets added to the exception or its wrapper then logging code will tell you exactly what happened and not leave you guessing with a mysterious stack trace.
If you care about writing code quickly, you’ll hate checked exceptions. But if you actually want to write robust code you’ll love them.
May 30th, 2007 at 10:38 am
Avery, are you suggesting that people who write in languages that do not have checked exceptions always write “fragile code” as opposed to your robust Java code?
Please take a moment to think this through.
Using unchecked exceptions, we can write robust code faster.
May 30th, 2007 at 10:55 am
Ravi’s point seems to be centered on what other languages implement, which is a bizarre statement, we are talking about Java right?
Checked exceptions are a *fundamental* part of the language, I didn’t even know this was up to debate.
Throwing a runtime exception when you can’t connect to the database is a horrible idea, you know you are connecting to an outside resource which can very likely fail, this should be explicitly declared and handled by applications. That’s the whole point of checked exceptions and why they are a good idea. Randomly throwing stuff up the stack and hoping somebody notices an error add unpredictability and does not lend itself to readable code.
May 30th, 2007 at 11:17 am
Gafter’s “research” on Google underscores a problem with the whole approach taken to changing Java. The process provides a forum for those who want a change to squabble loudly over the “best” way to do it, but it doesn’t give a voice to those who don’t want to “fix what ain’t broke.”
I see a tiny vocal minority of prima-donna rock stars with absolutely no awareness of, nor sympathy for, the masses who earn their living writing code instead of merely talking about how they could write code if they were to hypothetically stoop to such depths. Where does this little clique of oligarchs get off? They wrote some books? Big deal. Writing isn’t something that makes you an authority, it’s something you do after you’ve been recognized as an authority. You work for Google? Great, create your own language (again). Quit screwing things up for the rest of us.
One reason that I read this blog is because I like to hear from some folks with a respectable amount of good honest dirt under their fingernails.
May 30th, 2007 at 11:22 am
I reiterate, what is so special about Java that only it can create readable code? And that, too, because of checked exceptions?
How have other languages survived without using checked exceptions? How have robust applications been created without them?
So please explain the benefit of the code bloat with checked exceptions.
Even in Java, you can sub-class RunTime Exceptions and catch them. Using them avoids the requirement to declare the Exception thrown in a method,and then have each caller (all the way up to the point of entry into the system) either catch the Exception or declare it in a throws clause. Using RuntimeException, only the method that knows what must be done will need to catch it. The rest can be blissfully ignorant of it, primarily because they can do nothing even if they know of the Exception, they can merely pass it on.
Who benefits when a checked exception is merely passed up the call stack? The compiler, that’s who!
Remember that even RuntimeExceptions can be caught and handled. Now do you have any concerns?
May 30th, 2007 at 12:08 pm
I vote for a switch to another language, rather than hacks to Java. Since Java seems to be the only language with checked exceptions, this amounts to a vote against checked exceptions.
What is robust code, and what promotes it? The same code can theoretically be written without checked exceptions, so the difference with checked exceptions must be about communication and social effects. The question becomes: What is the social effect of checked exceptions?
On the plus column, checked exceptions provide a standard mechanism for communication about exceptions.
A casual review of this thread shows one social effect of checked exceptions I was previously unaware of. Avery suggests that Checked Exceptions help with cleanup. I believe that clean up should be placed in a finally block rather than in response to specific know issue, so that bugs (unchecked null pointer exceptions) and resource issues (out of memory) do not leave resources like database connections open.
The main social effect was mentioned in a previous communication by Elliotte. He had previously burried checked exceptions he felt were impossible. This creates the potential to hide an issue. The correct thing to do is wrap the ‘impossible’ checked exception in an unchecked one. Burrying exceptions is an extremely common social effect of checked exceptions.
For me one key principal it to try localize concerns in the code. In a web application that fronts a database there is likely to be a single consistent response to the database being unavailable. Using a checked exception distributes knowledge of this issue thoughout the code base. So even though this may be regarded by some as an environment issue, representing it in a checked fashion is likely to make the code worse.
In general, correct handling of exceptions requires:
1. Learn what exceptions can occur
2. Determine a response
3. Design the implementation of the response
4. Implement response
5. Testing of the implementation
I have not observed that checked exceptions make this more likely in the teams I have worked with. I have observed the anti-patterns caused by checked exceptions frequently.
May 30th, 2007 at 12:22 pm
Chalk up one more vote for checked exceptions. I suspect the reason why a “consensus” seems to be forming around removing checked exceptions is that there’s no real incentive for strident defenses of the status quo.
What seems peculiar to me about this debate is that Java already has an unchecked exception mechanism, so developers are free not to use checked exceptions if they don’t want to. What people seem to be asking for is a way to to avoid writing code to convert Exceptions to RuntimeExceptions when they use third-party or core java libraries. I would argue that the cost of such a change far outweights the benefits.
In languages without checked exceptions it is often _impossible_ to know how to handle an expected exception. For example, let’s say I want to make a call to a web service in C#. Nothing fancy. Just a simple method call. This is a place where I should expect certain types of failure conditions and handle them gracefully. So what should I catch? Trial and error shows that all kinds of exceptions might be thrown here: XmlExceptions, IOExceptions, InvalideOperationExceptions, etc. These cannot possibly be listed in the API documentation, since the underlying implementation can throw whatever exceptions it likes. The only course of action I can take would be catching ALL exceptions. But then I might swallow real unexpected problems that ought to be propagated up.
The only solution to this that I can see is coming up with a perfectly complete set of test cases. Sounds great in theory. But if you’re telling me that this is easier to do than correctly wrapping and handling checked exceptions you’ll have a lot of persuading to do.
May 30th, 2007 at 1:28 pm
I agree with Anders Hejlsberg’s statements that in most cases, most programmers, don’t care, and don’t really need to care about checked exceptions. However, I’m betting this doesn’t describe most people who write embedded apps — or anything mission critical that should halt only as a last resort (plenty of server side examples). Java’s checked exceptions seem to fit well in that type of code. It’s a benefit to have exceptions explicitly and specifically declared when you actually do intend to manage them.
May 30th, 2007 at 1:51 pm
Ravi,
Where is this “code bloat” from declaring checked exceptions?
All you have to do is add one line to your method declaration:
throws SomeException
You don’t have to catch it or do anything other than declare it.
If you find it’s so much faster to write robust code by eliminating the “throws SomeException”, you must be such a proficient programmer that copying and pasting a line (or using an editor macro to insert it) slows you down and bloats your code. If that’s so, then no, you probably don’t need or want checked exceptions. But you’re also the kind of guy who religiously checks error returns from C functions and decodes the value of errno, and also religously does bounds-checking on buffers (nope, no buffer overflows for you), so really, the whole question of writing robust code is not a problem for you. At all.
For the rest of us, it could be that checked exceptions have value.
If adding closures would discard checked exceptions, then don’t add closures to Java. Instead, make another language with closures and no checked exceptions, and have it compile the byte-codes. Problem solved, everybody gets to declare victory.
May 30th, 2007 at 2:48 pm
Bob, how gracious of you describe me without ever having met me. I definitely would like to meet somebody with ESP!
More seriously though, please confine your rebuttals to what I have explicitly stated, or whatever can be incontrovertibly inferred. Your statement about return codes are a vain attempt at distraction.
To answer your serious question though, here’s what happens.
Say, for example, I’m focussed on opening a file and reading its contents (not an easy task in Java, by the way.) I write the code, compile it. Or try to. The compiler tells me to handle the IOException. My focus is on the business of opening a file. If I can’t open it, I want to exit my system, let’s say, because everything I am interested in is contained in the file. But I can’t implement my business rule easily. I have to wrap my code in a try … catch block.
I beleive this slows me down. With IOException a RuntimeException, I would achieve my desired result.
If my business rule required that I try in a different location if the file were not found, then I would simply wrap it in a try .. catch block. This time it is not a waste of time, because it is required, it is a business rule.
What the API designers seem to be telling me is that they know my business rule, so make the compiler happy and write the try .. catch block anyway,damn it!
I do not think that the API designers know more about my users and business rule that I do.
This is just one instance, there are many more. JDBC comes to mind, so do the Reflection classes.
I hope I have clarified why I think Checked Exceptions limit my productivity.
May 30th, 2007 at 4:30 pm
Ravi, you don’t “have to wrap [your] code in a try … catch block.” Just declare the exception and let it propagate up the stack.
I don’t use this style myself. I prefer to chain checked exceptions, because 1) it gives me a chance to add context about what the caller was attempting when the failure occurred, and 2) prevents my abstractions from leaking.
May 30th, 2007 at 4:41 pm
I know that I don’t have to wrap my exception. But the point is, at the very least I have to declare it in the method signature; and it breaks my train of thought. Thus, it is unproductive.
Also, oftentimes, it will not be obvious why my method is throwing an exception.
May 30th, 2007 at 5:01 pm
Exactly. Which is why checked exceptions are so handy. There are probably a lot of methods that you might not expect to throw an exception. Especially if you’re invoking an interface whose implementation you don’t want to know about. Can it throw an exception? What type? So to write robust code, what are you going to do? Wrap every call in a try–catch block? Checked exceptions signal where it’s worth spending your time thinking about failures.
May 30th, 2007 at 5:09 pm
One difficulty is that this environmental versus programmatic distinction often depends on the particular invocation of a method, whereas the checked vs unchecked decision is hardcoded in the library when it’s written. For example, parsing xml which I’ve just serialized using JAXB would be a programmatic error if it fails, so would compiling an XPath expression which is held in a static String. Checked exceptions in these case are a bit of a pain. But in cases where the xml is genuinely ‘unknown’ (eg a user uploads an xml file), the checked exception is appropriate: same method, different uses.
Elliotte, you often argue against features on the grounds that they are complex/difficult to learn/difficult to use properly. Would you agree that even though the checked vs unchecked distinction is useful, that it can be a difficult one to make & that very often it’s not made correctly in APIs? If parts of even the Java API don’t get it right then perhaps it’s a sign that this is a feature that causes more hassle that it solves.
May 30th, 2007 at 5:27 pm
There’s a valid argument to be made that try/catch blocks clutter code. But to argue that *writing* them reduces productivity is a bit lame: in Eclipse, CTRL+1, ENTER to add a try/catch or a throws clause. 2-3 keystrokes.
Actually writing the text body of code is fast, what is slow is reading, understanding, testing, fixing.
If you really don’t want to think about checked exceptions declare every one of your methods as ‘throws Exception’ (but be ready for arguments if others call your code). Bad practice, but no try/catch or throws clauses to break your concentration. Generally what I do in unit tests.
May 30th, 2007 at 5:45 pm
Ravi,
No, you haven’t really clarified it.
If you’re that into writing your “business rules” that you aren’t thinking about errors, then you should first write some classes that represent your business objects to act they way you want. That is, if opening a file and not thinking about failures is important to you, then encapsulate that in a class that catches the checked IOException and rethrows it as an unchecked exception. In other words, you intentionally create the business objects that you then use to build your business rules.
As strange is it may sound, I have done just this sort of thing in some cases. Catch an IOException, rethrow it as a SQLException. Or vice versa. Also catch some RuntimeExceptions and rethrow as a checked exception. Or even catch a checked exception and rethrow as an Error. It depends entirely on what the “business rule” is, and what the “business object” is intended to do.
There is nothing in Java that currently prevents you from writing your business objects so they behave in exactly the way you want: unchecked exceptions everywhere. You can even start an open source project and get other like-minded people to contribute. It should be easy if the argument against checked exceptions is so compelling.
May 30th, 2007 at 6:39 pm
When I said earlier, “Also, oftentimes, it will not be obvious why my method is throwing an exception.” I meant that the fact that the method declaration tells me there is some Exception being thrown does not help me in figuring out how deep I have to traverse before I can know the exact class and method that throws that Exception which has been declared in all the callers.
It is the method declaration that says the name of the Checked Exception without giving me any meaningful information. The declaration of the CheckedException in the method signature is the root cause of my problem.
Runtime Exceptions I have no problem with.
May 30th, 2007 at 6:42 pm
It is much simpler to develop applications with very few checked exceptions. They are more robust, in my experience, than the false sense of security offered by checked exceptions.
That is why no other language has checked exceptions, and there is no request for its inclusion from any other programming language community.
Java sucks, checked exception being a big reason for that.
May 30th, 2007 at 6:49 pm
Bob, my point is that I want to spend more time thinking about the business problem, not about the plumbing I have to write ( try catch block, new class, what rot!) Why can’t I write simple code that works. Why must I strive mightily to please the Java compiler rather than my users?
Guys, you people have drunk the Java Koolaid; there is no point arguing with fanatics and those that refuse to see. I’m off this thread.
May 30th, 2007 at 8:05 pm
I must admit, ‘Java sucks, checked exception being a big reason for that’ fails my tests for a clear and cogent argument.
Checked exceptions are really quite useful, in my experience, as there are plenty of cases where the best person to handle a failure is some level up the call chain. Using judicious checked exceptions makes that fairly easy to do.
Both eclipse and idea make it pretty easy to add the appropriate throws clause, and you really should not care that much _who_ threw the exception unless you intend to handle it. Frankly, even then, I find that I can usually do the right thing without knowing much about who threw the exception.
Scott
May 30th, 2007 at 8:39 pm
Ravi:
“Why must I strive mightily to please the Java compiler rather than my users?”
If, after all this time, you still haven’t written the classes that make you more efficient in pleasing your users, i.e. by writing I/O classes to wrap the existing classes and rethrow unchecked exceptions, then that’s your problem, and you are refusing to address it. Instead, you blame the language and its existing library. The universe and everyone else in it should change to suit you, rather than you changing your direct interaction with the universe.
Get real. Coexistence is possible.
Lead by example and make I/O classes that throw only unchecked exceptions.
If you refuse to do anything like that, then I can’t take your arguments seriously. It’s obvious from your choice of actions (and inactions) that you don’t consider your own efficiency to be worth investing some time to improve. If you don’t believe your own efficiency is worthwhile, then why should anyone else believe it.
And this has nothing to do with drinking the Kool-aid. It has everything to do with addressing the problems that YOU see, and making it better for YOU. Talk is cheap.
May 30th, 2007 at 10:51 pm
From bob:
Lead by example and make I/O classes that throw only unchecked exceptions.
*sigh*
Are you seriously suggesting an alternative implementation of java.io, without the checked exceptions? How would this alternative “coexist”, given that many many existing APIs return objects from the java.io package? Or have them as method parameters? These bits are not, as rule, final (so can in theory be extended, when that’s an appropriate thing to do), but cleanroom reimplementation is not a trivial task.
Are you suggesting wrappers instead? That’s, if anything, worse; as a rule, it won’t be easy to pass wrappers in place of the wrapped objects, and you’ll spend all your time working around the dain bramage of the java.io API designers. Just to turn off the getCanonicalPath() silliness, you have to implement a wrapper that implements all the methods in File.
I’m still more or less on the fence as far as checked exceptions go; the proponents of runtime-only paint a picture of a lovely universe, where API designers can’t pull boneheaded tricks like having File.getCanonicalPath() throw a checked exception (that’s my favorite example of serious brain damage … get real, here, if you can’t find the damned thing to work out what its path should be, return a sentinel value, don’t toss IOException). On the other hand … if we lived in a universe where API designers thought carefully before placing a checked exception in a method signature, that might be even more attractive.
Part of the reason to dislike checked exceptions is, of course, the well-known antipattern:
try {
someMethod();
} catch (Exception e) {
// never happen
}
Naturally, it does happen, sooner or later. Hey, they wouldn’t declare the silly exception if somebody weren’t just *aching* to show off how well they can toss their … I mean, throw. Exceptions.
The extremely poor choice of exceptions to throw in many prominent Java APIs makes this almost irresistibly tempting (the dozenth time in one day that you write “thatFile.getCanonicalPath()” and your IDE or compiler smugly informs you that you need to declare the exception or catch it, breaking you out of the flow while you stare at it and snarl “bite me, hard!”, for instance). It’s one of the motivations to make these into runtimes (although in this case, for instance, I think it ought to be a sentinel value). An alternative would be: throw new NeverHappenException(e, thisProgrammer.telephone, thisProgrammer.timeZone, “This can never happen, so if it does, feel free to call me up and abuse me at top volume at 3AM years after I’ve moved on to greener (or less checked, in any event) pastures”);
Still, given a pet feature for Java, I’d rather see typed nulls than muck with closures and discussions of checked exceptions. The worst part about checked exceptions is that they are a sin already committed, and committed repeatedly every day, as the poor grunt programmers grit their teeth and deal with the “well, it *could* happen!” of some API designers.
Amy!
May 31st, 2007 at 12:17 am
[...] as one option that could simplify the closure specification. Some followups: Ricky Clarkson, Elliotte Rusty Harold, InfoQ. I’ve certainly been back and forth through the full pendulum of checked / non-checked [...]
May 31st, 2007 at 2:22 am
First, I hope we can all agree that Exceptions are good: The idea that some kinds of states/results are better handled by unwinding the stack to a point where the issue (not necessarily a problem) may be handled.
If we break down the Java exception handling mechanism there are at least four elements:
1. declaring an exception (throws …)
2. throwing an exception (throw …)
3. catching an exception (try/catch)
4. the distinction between RuntimeExceptions and other ones, and forcing other programmers to have to catch or redeclare other Exceptions. I’ve not seen any complaints about the first three, it’s the fourth one that is the issue. There are many ways of formulating the problem, the most interesting one (IMO) is “why do you think you know better than me that this is something that has to be handled (caught or redeclared)”.
Declaring an exception (whether uncecked or checked) is not the problem, it’s that it’s usually impossible for an API developer to know in what cases the exception is so important that it must be considered (caught or redeclared) by the direct caller. Rules of the kind “use checked exceptions when the problem is in the environment” or “use checked exceptions when the caller should know how to handle it” confuses forcing with declaring, it should be “declare the exception using throws when …”.
The Java API has enough examples of bad uses of checked exceptions that the feature should be removed. Note that the API’s need not be rewritten since it’s good that the exceptions are declared. We just have to remove the concept of checked ones, that the compiler (and verifyer?) enforces.
May 31st, 2007 at 3:31 am
RuntimeExceptions can be caught and handled. But how can programmer know he/she should catch some runtime exception? For example I’d like to catch database connection exception in web application, tell the user there is a problem with database connection and ask him/her for patience – database should be right in a few moments. But how can the programmer of web layer know which parts of backend code can throws any runtime exception? He/she need to search for it in documentation for every method he calls from his/her code. With checked exceptions this is not necessary. IDE and compiler helps to everyone with this.
May 31st, 2007 at 5:23 am
I think you are right. Usually who doesn’t like Java exception handling simply doesn’t understand it.
If the code has try-catch everywhere, maybe the code is not well written, and is full of “C-style” function returning an error code.
Try using “void” functions with “throws” keyword.
For my experience, more a program needs good error management, more the Java exception handling is effective and the code is cleaner.
Unchecked exceptions simply hide the problems…
Managing exceptions is not easy business, but is supposing problems will not happen the right decisions?
May 31st, 2007 at 7:54 am
Unchecked exceptions are the problem. No code that is capable of throwing an unchecked exception can be deployed to production. It is never acceptable for a process to terminate ungracefully. Every method must throw Throwable, all the way up to the top, adding on diagnostics as it goes, so that the application can either recover and/or put out an informative message and keep running–no exceptions.
May 31st, 2007 at 8:42 am
The same way other languages survived without static type checking or without garbage collection or without classes. Some things are easier; others are harder.
May 31st, 2007 at 10:14 am
Oh well, I couldn’t resist.
Frank says, ” No code that is capable of throwing an unchecked exception can be deployed to production.”
If that were true, one must always check for any code that could throw a NullPointerException or an ArrayIndexOutOfBoundsException (whatever the actual class name is.)
Do please think a little before you write.
As for Xan Gregg’s comment, he exemplifies the Java Koolaid mindset. Before Java came, other languages did pretty well.
Classes were a concept that date to the 1960s (Simula, then later Smalltalk). Garbage collection concept dates back to the 1960s in LISP and were successfully implemented in the 1970s I believe. LISP was way ahead of its time, and had to wait for hardware improvements to catch up to its features.
Do please read about other languages before you write. As many of the Java “leaders” are discovering, static type checking gives you very little advantage for the extra verbiage introduced. In fact, on balanace, for the good developers, static type checking is a net negative, I believe.
May 31st, 2007 at 10:36 am
“Checked Exceptions force the developer to deal with problems that in most cases are a bug — contrary to what you claim. Take JDBC. This API is riddled with Checked Exceptions that really indicate serious trouble rather than, “hey, we can deal with thisâ€. If I cannot open the connection to the application’s designated database for whatever reason then that’s really something that the application cannot recover from. So, Neal has my vote. And good riddance.”
A database server being down in a bug? So the next time my wireless drops out who should I file a bug with?
RuntimeExceptions are used to indicate bugs, yes, things like IllegalArgumentExceptionand IllegalStateException, or NullPointerException. Database connectivity, file I/O etc… are not bugs they are exceptions.
Checked exceptions are there to make programmers deal with expected failures. It is expected that external resources are not available. An application should most definatly graceully handle something like the database being unavailable - not simply crash.
If you look at C++ code search from the number of catch(…) occurances - in my expericence many of these are put in out of desparation because the developer has no idea what to catch.
A simple solution for all of this is:
add a new exceptionL CheckedException extends Exception
have all of the existing Java Library classes that currently extend from Exception now extend from CheckedException
hope that 3rd party developers also extend CheckedException.
Then all the people who want to be lazy wrt exceptions can declare that their methods throw “CheckedException” rather than Exception and at least the things that indicate bugs (RuntimeException and subclasses) would not inadvertantly be caught.
May 31st, 2007 at 11:51 am
Ravi
> Do please think a little before you write.
Please read and follow your own advice, there’s no need to insult people because they don’t agree with your point of view.
Static type checking is a step above old style C return error codes. I’m still not sure why you are proposing a “peer pressure” approach here, were a language construct is invalidated because it’s not present in other languages.
May 31st, 2007 at 12:02 pm
I not only thought before I wrote, I spent months going through tens of thousands of lines of legacy Java, implementing the strategy I outlined, in order to make the code capable of running lights-out (Sarbanes-Oxley, don’tcha know). And yes, that means NPEs. (Ever hear of optional message elements? Ever hear of careless requirements gathering?) The processes couldn’t be allowed to exit on NPE–or anything else, for that matter–because no one in the data center would have known how to stand them back up again; everyone who did know was being locked out. Cheap and sloppy to let that happen anyway, even in a more forgiving environment (footnote: no environment is ever as forgiving as you think it is).
May 31st, 2007 at 12:13 pm
I have been programming fairly well in C and in Java both for a loong time now, and boy, don’t I miss exceptions in C ?
Since I really need to ensure that all error conditions are handled properly. This is *bloat* of code for me. This is because I supply libraries, and most of the errors are caused by the incorrect parameters passed to my apis. There are errors I handle myself and there are some I want the api users to handle. I could deal with these neatly in Java, unfortunately not in C.
Checked exceptions require that you handle or pass-on any exception that might be critical. Atleast they ensure you are aware of them. I don’t like to throw them all just because it bloats my code. Does it really ?
May 31st, 2007 at 2:02 pm
> However, if you do understand the difference Java’s exception handling is the single best error handling and reporting mechanism ever built into a programming language.
Do Java people really think that?
May 31st, 2007 at 3:31 pm
In my mind, the issue is what to do about checked exceptions, not whether to distinguish checked from unchecked. I hold checked exceptions in high regard, especially right after some non-Java code bombs ungracefully on me with no explanation.
Currently, (most) Java compilers handle checked exceptions in a particular way that bothers some people. What about some alternatives? Could there be an annotation to suppress the checked-ness of an exception? Could there be a compiler option to 1) ignore any annotation and treat checked exceptions as they always have been, 2) honor the annotation but handle un-annotated methods normally, 3) never complain about unhandled checked exceptions, even if they aren’t annotated.
I haven’t thought this through, but it might address some good points made by Adrian Baker above that whether something is a runtime exception or not is context-sensitive.
May 31st, 2007 at 6:05 pm
Augusto: Throwing a runtime exception when you can’t connect to the database is a horrible idea, you know you are connecting to an outside resource which can very likely fail, this should be explicitly declared and handled by applications.
And what should this application do with the exception? What could the hypothetical app do to resolve the “can’t connect to DB problem”? Usually there is no reasonable way to resolve the problem, so there is no value in having the caller handle it. If you don’t know what to do with it the exception should be thrown up the stack until it hits a top-level handler and shuts down the app and/or notifies the user.
In my experience it is rare for anything but a top-level exception handler to have any business catching an exception. Why? Because it’s rare for low-level code to have any context for handling the problem.
My problem with checked exceptions then is that they encourage the caller to handle them right away rather than pass them up the stack.
May 31st, 2007 at 6:36 pm
“Augusto: Throwing a runtime exception when you can’t connect to the database is a horrible idea, you know you are connecting to an outside resource which can very likely fail, this should be explicitly declared and handled by applications.
And what should this application do with the exception? What could the hypothetical app do to resolve the “can’t connect to DB problemâ€? Usually there is no reasonable way to resolve the problem, so there is no value in having the caller handle it. If you don’t know what to do with it the exception should be thrown up the stack until it hits a top-level handler and shuts down the app and/or notifies the user.”
If there is no value in the caller handling it then you are saying “main” should crash, since main is ultimately the caller of all code (leaving out threads). However you are saying that main should shutdown the app and/or notify the user. I 100% agree that that is EXACTLY what should happen.
Now tell me how I am ssuposed to know that “foo.bar()” in an app can wind up throwing a “car” exception that I am suppose dto deal with?
Are you advocating wrapping main in a “try/catch(Throwable ex)? I hope not.
Checked exceptions allow you to do exaclty what you are suggesting - deal with the error in the best way - in the case you give exit the app.
Look at it from this point of view:
1) RuntimeExceptions ALWAYS indicate bugs in the code,
2) Errors ALWAYS indicate things your program should not try to deal with (save certain types of apps)
3) All checked exceptions ALWAYS indicate things that need to be handled in some way (shut down tha app, log a message, report to the user).
So a properly functioning program should NEVER throw a RuntimeException as it indicates a bug, and if it is a properly functioning system it should not have bugs.
If you start putting things like failure to connect to a database under the category of bugs the whole model breaks down.
“My problem with checked exceptions then is that they encourage the caller to handle them right away rather than pass them up the stack.”
Only in poorly written code…
June 1st, 2007 at 5:18 am
Adam,
You’re right that but you’re wrong that “it’s rare for low-level code to have any context for handling the problem” but you’re wrong that checked exceptions “encourage the caller to handle them right away rather than pass them up the stack.”
Remember, checked exceptions never require you to handle them right away. You’re always allowed to pass the buck up the call chain simply by declaring that your method can rethrow the exception. This is done with a
throwsclause. I’m not sure why so many programmers forget that.One of the beautiful parts of exceptions compared to traditional error handling is that you can in fact handle every problem in the most appropriate place because you have a separate return path for the exceptional conditions. In a non-exception supporting language, you ahve to define special return codes that may not fit the method’s type, or you have to stuff problems into global variables, and hope the right code remembers to look there. Exceptions are just so much cleaner.
June 1st, 2007 at 7:26 am
Unchecked exceptions for me, please, just so that’s clear.
Elliotte, we all know that “you’re always allowed to pass the buck up the call chain simply by declaring that your method can rethrow the exception.” But it affects your API! In a proper, layered application of any size, you usually don’t want your nth layer API to expose the exceptions that happen to be thrown in layer n+1. For instance, a SQLException may look weird in an API that’s part of your domain model. Any thoughts on how this should be handled?
My thoughts are as follows:
Provided you do checked exceptions, what you usually do with the SQLException is wrap it in an exception type belonging to the domain model layer. This could be a very specific type of exception, or a very general DomainModelException or something. But even if you make very specific exception types, you end up with a lot of them, and eventually you create the DomainModelException superclass, instead of having long throws lists in many methods. Then, as you add error handling (by throwing exceptions - you want the code to be robust right?) in the domain model layer, you will eventually find that all method signatures in the domain model layer declare “throws DomainModelException”.
And by this time, the “throws DomainModelException” declaration tells you nothing!
You have no meaningful information about actual error causes at compile-time, just a lot of declarations AND an enormous amount of catch (DomainModelException e) in the layer above you! You might just as well have used unchecked exceptions, that would have done the same job with less and simpler code. When your app does fail, you end up with an enormous nested exception to log (or present to the user), and have you noticed how only the innermost cause can tell you what happened? Usually “Connection refused” or something. All that you really needed was to get THIS one exception propagated to the application-level error handler - did you really need all the wrappers?
My advice to checked exceptioners is to try this out: Change your exception classes to extend RuntimeException. Track down all the places where you throw them, and see how the surrounding code is affected by not having to deal with it. Remove catch clauses that don’t add any useful failure information. The code usually becomes a lot simpler. Free of your chains (ha ha), exploit that freedom to throw unchecked exceptions more freely. Throw them where an error is identified, where you can most helpfully recount what the error IS. Eventually you will have robust code, because robust code is code that reports errors early and avoids bad state, not code that constantly tells the compiler “oh, and something may happen when this runs, so please force me to worry about it everywhere”.
A less time-consuming exercise is to count the places you throw an exception, and compare it to the number of places your either catch it or declare it. Also, take a long, hard look at the actual exception instances you actually see in logs, and honestly gauge their useful information content.
Sorry about the emotion (and length), but there seems to be a lot of that here already.
Checked exceptions must go! Have a nice weekend.
June 1st, 2007 at 7:27 am
I too am for checked exceptions and I think it was a bad idea to not take them over to C#.
I have no need of closures and if it comes to an either or situation, closures should be left out imo (not that they necessarily have to be added if checked exceptions stay in, as far as I am concerned).
At least with checked exceptions I know what I should take care of (or at the very least what I should think about taking care of) instead of being caught completely off guard and shutting down the app as the only reasonable response.
As for the DB not reachable exception, what the app should do (instead of falling on its face) is telling the user that the DB is not available and asking whether he wants to retry or connect to a different data source (assuming he can choose between them in the first place). I.e. it should recover gracefully and not just crash (as it generally would do with an unchecked exception).
June 1st, 2007 at 8:10 am
We usually have low level code throw back many of those exceptions, and the higher levels of the business logic are mostly concerned with knowing if the operation failed or not. Checked exceptions are great because you can write your code assuming everything worked fine, while you have a separate block neatly handling the error conditions.
If the DB is not available, in some of the apps I’ve done, we have a mechanism to go to another backup DB. We also have to log that, and return an error (remotely) to the client process to let them know of the failure.
I guess I’ve never worked on an app where it was OK to halt your application due to these things, i’m talking about big applications, not little scripts. To me, bubbling up every possible error and hoping it’s handled magically is not a good idea.
June 1st, 2007 at 8:25 am
It IS possible to handle exceptions even when not instructed to do so by the compiler. Some exceptions (and I mean actual exception INSTANCES at runtime, not exception TYPES at compile-time) need to be caught NOT because they are of a certain (compile-time checked) TYPE, but because they have made it to a certain POINT in your main control flow. Say something as simple as a loop reading from stdin and parsing commands. When a command fails on, say, an IllegalStateException, you need to catch that too (and log it, report it, whatever), even if the compiler didn’t tell you about it.
June 1st, 2007 at 11:35 am
Elliotte, I could not agree with you more. Checked exceptions, it should be said, also force the caller of modular systems to deal with the improper or lazy implementation of module interfaces, because such implementations often break in unpredictable ways.
One poster above says something about how my goodness, once you start wrapping exceptions, ultimately you end up with some non-specific DomainModelException and then you’re hosed for all time. How does this follow, exactly? Normally you define a checked exception type that is germane to the layer—PersistenceException, PresentationException, etc.—and use that to wrap the lower layer exception. When you’re done, you have something roughly akin to a geologic slice of your application that is available to the top “catcher”, who, at that point, can mine the layer stack to figure out exactly what went wrong. Each layer exception also has the ability to add information to the error (something that RuntimeExceptions taking the express elevator to the top cannot do, since the elevator doesn’t stop on any of the floors of the layer stack). So your persistence exception can tell you things about who the current user was at the time, whether caching was in effect or not, etc. etc. Your UserManagementException wrapping that can add more details about the user at the time, and finally when the whole shebang gets to the top your error handler can say exactly who was trying to do what, when, when the root error occurred. That can’t be done with RuntimeExceptions flying up from the bottom, unchecked.
I’m beginning to think the RuntimeException crowd simply doesn’t like writing catch blocks. I mean, really, does the argument against checked exceptions amount to anything more than “I like my code to use as few keystrokes as possible”? If that’s the case, why would you write in Java in the first place?
June 1st, 2007 at 1:56 pm
When I said “It IS possible to handle exceptions even when not instructed to do so by the compiler”, I meant to point out that unchecked exceptions can be caught as well. A bit sarcastic at the time, but now I do begin to wonder. But everybody know this right? I am uncertain how to interpret statements like “the elevator doesn’t stop on any of the floors of the layer stack” and “that can’t be done with RuntimeExceptions flying up from the bottom, unchecked”.
Of course it can. Unchecked at compile time does not mean uncaught at runtime. The compiler does not catch your the exceptions, the runtime does. They’re objects, not types. Try it.
June 1st, 2007 at 2:45 pm
Nobody wants to guess what exceptions your call might throw, and no, it’s not enough to put it in the comments.
If your call is likely to fail due to a non-bug condition, I need to know about it so I can take care of it. Simple example is remote vs local calls, a million things can happen to a remote call, while calling your local 2+2 method won’t fail unless there’s some catastrophic condition. If you can fail twoPlusTwo() because it touches a network, a database or some other condition you need to somehow express that either directly or in your own new exception type, but I need to know about it. Not knowing about it is really poor engineering.
June 1st, 2007 at 3:40 pm
My vote for checked exceptions
June 1st, 2007 at 7:35 pm
Sigh. I think most of the people that want unchecked exceptions have it exactly backward. We want to replace the need for UNCHECKED exceptions. Notice i said “replace the need”.
Those ugly nested exceptions blocks of code you see around code for error correction? Why do they happen?
Oh right. Its because the stream might be null. Or already closed. Or maybe we’re casting incorrectly.
Now what do those exceptions have in common?
What we do want is a (brief) way to enforce non-nullness, or catch all inside unchecked exceptions, inside a cleanup catch.
Wankers.
June 1st, 2007 at 10:05 pm
Just out of interest, which of the following is correct?
String doSomething(File a, File b) { try { String x = a.getCanonicalPath(); String y = new File(b, RANDOM_CONSTANT).getCanonicalPath(); if ((x != null) && x.equals(y)) return x; return null; } catch (IOException ioe) { System.err.println("One of the supplied files had a problem, so they can't possibly match."); return null; } } String doSomething(File a, File b) throws IOException { String x = a.getCanonicalPath(); String y = new File(b, RANDOM_CONSTANT).getCanonicalPath(); if ((x != null) && x.equals(y)) return x; return null; } String doSomething(File a, File b) { String x = null, y = null; try { x = a.getCanonicalPath(); } catch (IOException ioe) { System.err.println("a had a prollem, too bad, not matchable"); return null; } try { y = new File(b, RANDOM_CONSTANT).getCanonicalPath(); } catch (IOException ioe) { System.err.println("b had a prollem, too bad, not matchable"); return null; } if ((x != null) && x.equals(y)) return x; return null; }When considering your answer, please ignore the suckage of standard java brace positioning style that makes it *all* wrong, and the inherent triviality of the example. The issue is:
you want to catch one exception.
more than one exception of the same type can be thrown.
going up the stack is not going to reach a method with *more* knowledge about the suckage of these particular files in this particular file system (how often do you *gain* information going up the stack? if your answer is “often,” does your company have any job openings?).
null results from the method are expected, as a sentinel value indicating no, false, indeterminate, none of the above, never mind, 42.
yes, i know it can throw an npe. you wanna see it with guardian code against null?
if your answer is #1: why is it okay to lose information about what had a problem?
if your answer is #2: why is it better to have something higher in the stack deal with this?
if your answer is #3: please stay at your current job; i *never* want to read your code, hand, kthxbye.
June 2nd, 2007 at 8:19 am
answer is #2: the caller of this function already deals with file-objects, IOExceptions should be expected when using files
June 3rd, 2007 at 10:32 am
Amy! seems to want to point out that two distinct failures can occur here, while the declaration of IOException can only tell you that an exception of that type can happen.
By the way, IOException is exactly that kind of exception I talked about as DomainModelException, just for the domain of I/O. Notice how most methods in the io package declares just IOException? Not long strings of FileNotFoundException, EOFException, FileLockInterruptionException, InterruptedIOException, ClosedChannelException etc. It’s not useful enough to defend all the clutter. If we did the long, specific throws lists, wWhy should we stop there? Since file systems MAY be network file systems of some sort, and you WANT to know about that: ConnectException and UnknownHostException SHOULD be declared as well. Maybe there’s HTTP involved, so we need HttpRetryException declared as well.
Instead, we don’t. We bubble up the API layers with more general exceptions like IOException, and at runtime we wrap them in each other, to reflect the layers involved. Only once we do a wrap, and here comes the conceptual leap, we lose that precious, static, compiler-treatable information that checked exceptioners want. We have the declarations of IOException, but that information is too shallow to be useful to anyone but a pedantic compiler. To have exceptions be useful in a bigger system, we have to “mine” them for info - as objets, at runtime - as Laird pointed out.
Amy! points out another weakness, namely exceptions that deal with separate instances which can provoke the same type of exception. You don’t want to subclass all File-related exceptions to FileANotFoundException and FileBNotFoundException, so this is just another reason you can’t express it statically in a scalable way.
In fact, when engineering a bigger system with sophisticated failure scenarios, I don’t think the choice of checked or unchecked exceptions matters. Given experienced enough engineers, the checked exceptioners will simply experience the higher overhead of maintaining matching throws clauses and re-throws.
June 4th, 2007 at 6:53 am
“Java’s exception handling is the single best error handling and reporting mechanism ever built into a programming language.”
Sure.
And JDBC is the fastest SQL interface ever implemented, J2EE is the most scalable web framework ever designed and JNI the most practical native interface ever devised, etc …
Plese stop it.
Java stands where worse is better, where an infuckingcredibly complicated language produces monstruously sophisticated applications that run like slow cows … and generate a lot more profits for service providers, software integrator and hardware vendors. Any competent Java developper knows *why* Java succeeded in entreprise and failed miserably everywhere else.
It’s ok not to tell gullible customers about that sting, but please spare us that marketing crap for dummies.
June 4th, 2007 at 8:26 am
Yes, because C# does not have checked exceptions, then they should be removed from Java as well. C# is a better language than Java, in many ways:
1) C# has multi-line string literals
2) C# has operator overloading
3) C# has string compare with ==
4) C# has better primary types (int vs Integer)
I don’t know if it is possible to remove checked exceptions from Java, but if they do it, then Java is one step closer to C#, a little bit easier to develop with. I hope that they continue with the other above mentioned things.
June 4th, 2007 at 8:36 am
As I understand it, removing checked exceptions is a matter of modifying javac, effectively taking the check out of checked exceptions. It’s a compile-time thing only (… the virtue of compile-time things having been heftily testified to in this thread.)
June 4th, 2007 at 8:49 am
Amen brother!
Yes, checked exceptions are a pain. It’s so much easier to just ignore problems. Let’s all go back to C++, where we can just ignore return codes, malloc returning NULL and everything else. That was better. NOT!
June 4th, 2007 at 9:28 am
Coming to removing checked exceptions, the rationale seems to be :
“Remove any feature that gets in the way of BGGA closures (or makes them even less tolerable), force closures into the language, and, et voila, we’ve improved the language!!”
June 4th, 2007 at 9:42 am
I agree wholeheartedly, checked exceptions are a good thing when applied according to section 8 of Effective Java. Anyone who is voting against them should please read that section before placing their vote. If you *still* feel that way after, feel free to cast your vote against mine
June 4th, 2007 at 9:47 am
Here’s my vote in favour of checked exceptions.
Ever programmed a large C system? Nearly every other line is error handling. Oh for an exception mechanism.
Ever programmed a large C++ system? Everybody throws std::runtime_error as soon as something goes wrong; nobody declares anything and the you end up with core dumps and no explanation.
Ever programmed a large Java system? Methods declare exceptions and callers have to decide what to do - catch or declare. Having to decide is a good thing and the compiler enforces it so lazy programmers have to decide.
June 4th, 2007 at 10:58 am
Kjetil Valstadsve - you are the _ONLY_ non-emotional commenter on this site that has offered a clear, rational and detailed explanation about why checked exceptions are harmful. Not the productivity claim, not the code bloat claim - though checked exceptions indeed cause bloated code , but the correct statement - they simply break OO and are harmful for software design in the long term. The most hated checked exception in this category is the java.rmi.RemoteException - I hated it from the very first day I knew RMI (Kept saying to myself - OMG this breaks OO - I cannot believe that the designers actually thought this was a bright idea).
Propagating low-level exception types by declaring them in the throws clause of all client interfaces (the solution that ERH recommends) is a VERY, VERY, VERY bad practice that completely destroys one of the primary principles of object oriented programming - decoupling of contracts and implementation.
Kjetil has already described the problem well, but let me add my 2 cents. If I create an interface, for example say ‘Paginator’ which paginates rows, I DO NOT want to declare an SQLException in the getNextPage() menthod if the db implementation of this Paginator fails. Why? because in using that horrible declare clause you have coupled my Paginator interface with its db-specific implementation. In the future (or in unit testing) if I want to provide use an in-memory, local Paginator, that implementation will also need to declare that completely useless exception.
What do the group of checked-exceptions proponents who are also OO purists advocate to solve this problem? Oh..you simply wrap up the underlying exception..in your case the SQLException in a PaginatorException class and declare that instead. So basically everything starts looking like this
public interface Paginator {
List getNextPage() throws PaginatorException
List getPrevPage() throws PaginatorException
…. throws PaginatorException
}
(Note: OO purists please don’t complain about the non-generified List return type there - this is an example)
So now we have all our caller-code in the next layer which uses Paginator (assume its code that paginates over Product listings) to do this:
…
try {
List productListing = paginator.getNextPage();
} catch (PaginatorException e) {
throw new ProductListingException(e);
}
…
This is quite silly IMHO - it may be more OO but you have lots of boilerplate code doing nothing but wrapping and re-throwing exceptions. And you have that brain-washing ‘throws LayerException’ text in every method signature. That wrapping code takes CPU time and these deeply nested exceptions objects cost memory which can be better utilized elsewhere.
I would rather use unchecked exceptions and propagate them to the top error-message display code. _IF_ the error-handling logic code has unsufficient contextual information to determine which error message should be displayed, ONLY THEN would I introduce a new LayerRuntimeException class that would wrap the underlying fault, add some context data and re-throw it. The advantage of using this versus a LayerCheckedException is that it does _not_ force every layer above me to create a brain-washed-possibly-do-nothing-but-just-sitting-there LayerAboveCheckedException or alternatively declare a ‘throws LayerBelowCheckedException’ in the LayerAbove interface method signatures (which completely breaks OO).
Designers of popular Java frameworks are moving to unchecked exceptions. Hibernate is the best example. They moved to unchecked exceptions in 3.0. The JDO commitee decided to use unchecked-exceptions in their API design - ruling correctly that checked exceptions in an API have little or nothing to do with error handling.
I believe the ONLY case where one can introduce a checked exception in an API signature is when the API excpects that exception MUST be immediately handled by DESIGN. This is dependent completely on the problem domain and is usually around 5% of all the exceptions floating around there.
Btw.. I support the use of unchecked-exceptions in new API design. I DO NOT support removing checked exceptions as a language feature in Java just because some bright geeks decided it didn’t work well with their closure proposals. Thats a nutcase argument - completely turning a blind eye to all the APIs and code out there - put forth by people who really should know better.
June 4th, 2007 at 11:05 am
People who want to remove checked exceptions do not understand what Java is all about. This language never tried to be the fanciest tool a computer scientist could use. There are dozens of languages trying to be that. Java is about help writing robust everyday code. Many people that need to get robust work done use this language and their APIs everyday. And Java is especially great for writing code that can be easily understood and maintained by other people. It is so verbose, that it is almost self-documenting. I consider this as a great feature. Checked exception are an indispensable part of writing such maintainable code. This is not the idea of people too lazy to think but the insight in the doleful fact, that most of the work of a programmer is not implementing cool algorithms in as few lines of code as possible, but maintaining programs written by others. And it can not be overestimated how glad you are if your predecessors working on the program where forced to declare error conditions that might occur at a certain point!
Checked exceptions are one of the most important features of Java and a reason why this language is so successful. Scripting people that mainly write short programs on their own and had never maintained another persons code might not share this view, as they also tend to see static typing not as a bug and not as a feature for writing robust code.
There are many programming languages for writing cool code. Just use one of them. If you are forced, by some reason, to refer to Java libraries in your code use Groovy or JRuby. I like Groovy very much. There is really no need to make Java yet another scripting language as there isn’t a need to over-engineer it to get on par with C++ or ADA. Java as it currently is, is designed for square, robust code and many people are contend with that. If someone really thinks, that C# is better designed than Java, why not use it? Go ahed and try to figure out which exceptions are thrown at which method call in a lib or what operators are overloaded for which types. Have fun with it, but I personally do not enjoy this.
June 4th, 2007 at 12:02 pm
Checked exceptions are really only useful if the developer can do something reasonable to resolve it. Most often they just let it go all the way up the call stack and report it, in which case it might as well be a RuntimeException anyway.
June 4th, 2007 at 12:06 pm
No the language certainly isn’t the fanciest tool a computer scientist could use. See Haskell for that.
However, this language is definitely for the software designer who creates enterprise frameworks and their API sets, and application programmers who create applications on top of those frameworks. Also this debate is _not_ about static typing, so lets not muddle clearly distinct issues here. I am a strong proponent of static typing as I believe it self-documents code and really doesn’t add all that rigour that the XP crowd keep complaining about. My argument was that the usage of checked exceptions in the manner recommended by ERH clearly breaks object-orientation - and OO is one of the principles that you need to religiously stick to when designing enterprise frameworks that will be used and maintained by hundreds of diverse programmers over a long period of time. Speaking from practical experience - I have worked on a 100GB codebase product used by millions of end-users and worked on by hundreds of developers - once you break OO principles, you tend to accumulate garbage that ruin things in the long run.
June 4th, 2007 at 1:03 pm
Tarun Ramakrishna Elankath, let me make sure I understand. You have some abstract component with a few implementations. These each throw unchecked exceptions of various types. Now an application is using this abstract component that can throw any type of exception. If the application catches any implementation-specific type of exception, the abstraction has leaked and your object orientation is destroyed. So the only type that makes sense to use in a catch clause is Exception. And if that’s the only type to be caught, why throw anything else? Following your argument, Exception should be final, right?
June 4th, 2007 at 1:27 pm
a very good article about using checked and unchecked exceptions:
http://dev2dev.bea.com/pub/a/2006/11/effective-exceptions.html
June 4th, 2007 at 2:39 pm
I’ve never really understood this debate. Despite all my complaints, I’ve never had a problem with checked exceptions.
A good friend of mine is very much in the “no checked exceptions” camp. I recently showed him some recent multi-threaded I/O code that I’m working on. The question I put to him was “So, what am I doing wrong here? Checked exceptions seems to work great.” On reviewing my code, he says (more or less) “Well, in your case, yea. Looks good.”
Why is that?
I think it’s because of my program’s design. The way I understand the “no” position, when a checked exception is thrown, you typically aren’t in a position to do anything about it. But in my case, I am in a position. Due to my design.
So now I think that everyone complaining about checked exceptions are misidentifying the problem. I recommend designing programs to take advantage of Java, not fight against it. And if the library or framework misuse checked exceptions, that’s a regrettable, but not really a problem with the Java language.
(It feels good to agree with Elliotte Rusty Harold. First time for everything… )
June 4th, 2007 at 3:06 pm
There is no leak. At least, it’s not a static leak. It’s the same with code written against an interface; at runtime, you have an instance of an implementation class. You don’t call that a leak either.
PaginatorException wraps an SQLException in one case, but the API does not reveal that, statically. At runtime, actual errors needs to be revealed somehow, and the Throwable type (getMessage(), getCause()) is usually enough to print all relevant info and learn more about the application’s common exception situations. That learning should be used for more sophisticated, automated analysis. Adding them statically to the interface is not a good idea, since that would tie it to one application, and wreck all your reuse options.
And as I’ve said earlier, at some points in the control flow you just need to catch whatever comes at you, and simply not die. A servlet container doesn’t drop dead (or leak I/O resources) when an application exception gets thrown during a request - it catches whatever it is, even exception types that didn’t exist when it was compiled, and at worst you get a stacktrace in your browser.
June 4th, 2007 at 3:59 pm
Checked exceptions are mandatory if you want to write robust code. If we eliminate the throwing of IO exceptions on function signatures, then all coders will forget to catch exception on the call, leading to bad delivered code in the field. Others will execute all code in a try catch block that catches Exception at the highest level of code. Then they will print the exception.getMessage() text to the user. This will not allow them to handle problems differently, unless they do a switch statement on the exception message text, which is a maintenance nightmare. I would rather have the compiler tell me problems than have unexpected runtime exceptions being thrown with the coder choosing a poor reaction to the problem, like shutting the app down in mission critical application.
One of the comments above makes the statement
“Checked exception here gives no benefit except to the consultant who write bloated code or gets paid by the number of lines of code/time spent.”
Maybe that coder should use Eclipse to automatically add in the try catch blocks using a right click menu option. I think this extra piece of work provides a cheaper total cost of ownership than not having checked exceptions and the coder having to write some hoaky try catch statement at the top level of the code. (Can you guarantee that the code’s response is correct for the problem and did you catch all the problem cases? You will probably now have to interpret each line of code that you call recursively to deduce all the failure conditions. What a headache! And how about if some of that recursive code is in a 3rd party library in which you don’t have source code. Your in deep trouble! Can you ensure this is comprehensive and can you get all this done in less time than just implementing the checked checked exception and have the compiler tell you the problems in an IDE, double click on the problem, the IDE navigates you to the line, right click and select “Surround with try catch”? What about if you were the lead of a team of young Java programmers and this was your approach to dealing with errors. You would be way over budget, guaranteed.) In my mind, if you don’t want checked exceptions, use a scripting language because you are not building a mission critical app.
It seems like all this agile test driven development is pushing the language to do new things. We need to be careful that simple, small, application creation by a single developer does not drive the Java language. We must consider maintenance as a key measure of goodness when trying to decide if a feature is good or not. If we don’t and allow Java to be a whatever scripting language, we will have yet another scripting language and one fewer good programming language.
If this is the case, Java is on a death march.
June 4th, 2007 at 7:50 pm
I absolutely 110% completely agree with ERH.
I’d even go further:
Checked exceptions are about rock solid robustness. Yes, there are two types of idiots that don’t like them
(1) Those that don’t understand them
(2) Those that misuse them
#2 is treatable with education
The thing that the java guys are doing right is having these discussions in the open. Languages _should_ be developed in the open. Contrast this with Objective-C (which is the thing I’d switch to if I left Java)… the next version of this is being developed behind closed doors, which creates huge uncertainty for me as someone that might want to write software for that platform.
June 5th, 2007 at 12:43 am
Checked Exceptions are useful in some case, it should not be removed. If you don’t like it, just don’t use it!
June 5th, 2007 at 1:30 am
In Java, developers are mandated to deal with checked exceptions. In .NET, developers can completely ignore them, since the framework doesn’t force you to deal with them.
I would love feature set like below:
1. We should have compiler flag which can enforce or ignore checked exceptions.
2. If enforced, compiler should provide warnings
3. If ignored, Java should mimic .NET (Compiler will be happy whether exceptions are handles or not)
In this way, the Java language platform itself should be able to remind developers of any checked exceptions (If and only if the developers like to be reminded), but developers should also be able to write “only business solutions code”, not always “exception handling code” (again, if he likes it that manner).
You may also like to go through this link: http://www.iasahome.org/c/portal/layout?p_l_id=PUB.1.362
June 5th, 2007 at 2:23 am
My vote goes for Checked Exceptions, too.
But it might be interesting to have a javac option to disable this checking.
Then we can come back in 5 years and see how many *big* projects out there decided to use that switch for code base.
I just fear that this might damage the reputation of the Java language in general
June 5th, 2007 at 3:55 am
Checked Exceptions are needed. It’s necessary to force programmers to handle certain errors (like those in io). You can’t expect that they think about every possible case BEFORE it happens.
Don’t fit everything in Java. Why not define another language (maybe based on Java) compiling to Java bytecode?
Some competition would be great!
Just my 0.02$
June 5th, 2007 at 6:16 am
>Checked Exceptions are useful in some case, it should not be removed. If you don’t like it, just >don’t use it!
I agree!!!
I think Checked exception is a great idea.
Should keep it, must not remove it!
Mr Einstein said: “Make everything as simple as possible, but not simpler.”
I always to think it over when compare java with C#.
I like java because it “Make everything as simple as possible, but not simpler.”,
C# doesn’t do it well.
I doubt if it’s just like a women say: “I want some new clothes”, when the C# designers want to add a function. Sometimes may they don’t know if they desire or C#(or programmer) really need, I think.
Come back to “checked exception”, I have hear few programmers around me to complain “checked exception” take trouble to them, except some famous commentator announce it.
June 5th, 2007 at 6:41 am
># Harri Says:
>June 4th, 2007 at 8:26 am
>
>Yes, because C# does not have checked exceptions, then they should be removed from Java as >well. C# is a better language than Java, in many ways:
>1) C# has multi-line string literals
>2) C# has operator overloading
>3) C# has string compare with ==
>4) C# has better primary types (int vs Integer)
>I don’t know if it is possible to remove checked exceptions from Java, but if they do it, then >Java is one step closer to C#, a little bit easier to develop with. I hope that they continue with >the other above mentioned things.
According your logic, I think C++ is much better than C#
1), C++ let you destroy memory by hand, C# can’t.
2), C++ let you write global method, C# can’t.
……
When you compare two programming language, I think you should not list what they can do, what’s can’t do.
You should ask which can finish my work better.
People always like the (spider, super)man (thing) which can do every thing.
Scientist mostly like the simplest thing.
June 5th, 2007 at 9:13 am
“try {
List productListing = paginator.getNextPage();
} catch (PaginatorException e) {
throw new ProductListingException(e);
}”
I once saw something where someone was advocating writing an application based on strictly adhering to the ISO OSI 7 lay model. Essentially this is the argument being given here that each layer cannot have much knowledge of the layer beneth it. From a theoretical point of view it is an excellent way to write a program. In practive it is a great way to write a program. Unfortunatly the peple writing the application took it to an extreeme and each layer has a SINGLE method that was used for the layer able to communicate with and then it would shunt the calls to the appropriate method.
The people advocating the domain exception handling here are making the same mistake.
IMO you did the proper thing by having the code throw a PaginatorException. IMO you should not have caught it and morphed it into a ProductListingException.
The same goes for the argument about IOException being thrown everywhere. That is why I have methods declared with 7 types of exceptions rather than a single domain one. I use domain exeptions frequently, where it makes sense. I ALWAYS declare EVERY exception I throw (runtime ones too) in the javadoc. When I catch the exceptions I usually deal with a few of the specific ones and then catch the parent one for the rest depending on the how things are going to be handled.
Saying that the designers of the java.io APIs made a mistake (throwing java.io.IOException instead of the sepcific exceptions) so we should all make the same mistake too is a bad idea. Learn from mistakes and try not to emulate them. Do not dogmatically follow the diea that one layer should not be aware of the layers used n+2 below it. Many times that makes sense, other times it makes the code far harder to understand. Go for understanding over dogmatism.
June 5th, 2007 at 10:34 am
In general how do you know that code throws unchecked exceptions? If you don’t know it throws it, how do you know the catch it?
And if you think Java sucks, why are you reading this blog?
June 5th, 2007 at 2:08 pm
A question for those who are advocating unchecked exceptions to make the API “cleaner” and to keep abstractions hidden:
If you only have unchecked exceptions and you want to switch between, say, JDBC and another database access layer, how do you go about changing your code to deal with the error cases?
Given I have some ideas on how I would do it, and none of them give me a warm feeling, I want to know how you would go about it in practice. Perhaps there is something that the “Checked Exceptions” isn’t aware of when it comes to a strategy for dealing with this sort of thing.
June 5th, 2007 at 4:24 pm
D’Arcy, I don’t really understand what your modus operandi really is, but here’s mine.
I prefer to trap all calls to methods that declare a checked exception, and wrap at exceexception in an application-specific, unchecked exception. It has a message stating the purpose of the call, important input values etc.:
try { db.load(that) } catch (DBException e) { throw new AppException(this + ” failed to load ” + that + ” from ” + db, e); } // etc
That’s one half. The other is a centralized exception handler, as opposed having to catches and handlers all around. Just like with any other piece of logic, the DRY principle is in effect for error handling as well.
To sum up: Re-throw exceptions where they happen. Handle failures in a single place. At least for simple, synchronous, request-driven logic like web apps, this scales well.
It comes down to the fact that a database is a complex piece of software that might behave strange at times, and obviously the compiler can’t uncover all the corner cases for you. You need a learning process, where you find out what they are, and how to avoid them. I like the immediate re-throw because it hides no information from me about what happens, and it keeps my focus on the application failure logic - ie. my own exceptions. Since they’re unchecked, refactoring them into a meaningful hierarchy is easier, and the exception handling logic can be tuned over time. If they WERE checked, I would probably have AppException (I once did) declared everywhere, which to me carries no more meaning than having it declared nowhere. No magic here, just hard work
June 5th, 2007 at 8:24 pm
>If you only have unchecked exceptions and you want to switch between, say, JDBC and another >database access layer, how do you go about changing your code to deal with the error cases?
I think this is a program problem. not a programming language problem.
In my view, you could resolve this problem easily by writing an util method or an adapter class.
The most beautiful and difficult thing: it’s same what the programming language just do, and what the programmer just do, from the view of language designer and language user.
June 6th, 2007 at 9:34 am
I vote for checked exceptions too.
June 6th, 2007 at 10:38 am
I completely agree. Checked exceptions are a core feature that makes programs in java safer to run. The fact that it takes a bit more time to grasp the idea of how to use them properly does not mean we should let them go.
June 6th, 2007 at 12:13 pm
“D’Arcy, I don’t really understand what your modus operandi really is, but here’s mine.”
See the end of the post for my motive.
“I prefer to trap all calls to methods that declare a checked exception, and wrap at exceexception in an application-specific, unchecked exception. It has a message stating the purpose of the call, important input values etc.:
try { db.load(that) } catch (DBException e) { throw new AppException(this + †failed to load †+ that + †from †+ db, e); } // etc”
Well that is exactly what I would do as well, except that DBException would be Checked. I don’t understand what you think you are getting by making it uncheked? (yes I know you answer it below)
“That’s one half. The other is a centralized exception handler, as opposed having to catches and handlers all around. Just like with any other piece of logic, the DRY principle is in effect for error handling as well.”
Checked exceptions don’t impede that either (yes I know you answer it below).
“To sum up: Re-throw exceptions where they happen. Handle failures in a single place. At least for simple, synchronous, request-driven logic like web apps, this scales well.”
Ok, how do checked exceptions impede that at all? (yes I know you answer it below)
“It comes down to the fact that a database is a complex piece of software that might behave strange at times, and obviously the compiler can’t uncover all the corner cases for you. You need a learning process, where you find out what they are, and how to avoid them. I like the immediate re-throw because it hides no information from me about what happens, and it keeps my focus on the application failure logic - ie. my own exceptions. Since they’re unchecked, refactoring them into a meaningful hierarchy is easier, and the exception handling logic can be tuned over time. If they WERE checked, I would probably have AppException (I once did) declared everywhere, which to me carries no more meaning than having it declared nowhere. No magic here, just hard work :-)”
IMO you are being lazy. Simplifying refactoring at the expense of knowing what exceptions are thrown is, IMO, not a good idea. I recently tried something, I wrote a a semi-large program that had several possible failure points in it (a client/serer app where neither part was allowed to crash). For each error case I did “throw new Error()”. After the app was done I did refactoring and putting inthe proper exceptions. Yes it took time to go through and put in all the “throws” clauses, but looking at the API it was absolutly clear what was going on, and I found a few places where the design needed cleaning up as well from it. The effort was well worh the time. If I had used runtime exceptions it would have been much harder to check that I was doing things properly and I would not have seen the design errors.
My motive for asking was to find out what people think they gain by using unchekced exceptions. IMO you method is fine (except for the fact tat you declare the abstracted exception as unchecked). What I was wondering was, if SQLException were uncheked would people go about catching it and then have to reqrite their programs to adapt to a new exception when they changed the persistance mechanism.
June 6th, 2007 at 1:13 pm
I vote for keeping checked exceptions, too. Removing checked exceptions for the purpose of making the addition of closures easier is one of the funniest proposals yet. I hope that this is just a joke.
June 6th, 2007 at 2:21 pm
In C, when a function returns an error code, you must test it and, if there’s nothing you can do about it, you must “rethrow” the error code manually. This is annoying.
In C++, C#, Delphi, D, Python, etc., you simply write your code. If an error occurs, it will simply unwind the stack until a handler is found (some of these languages are better than others since they provide a default handler automatically around main, but this isn’t the point here). Perhaps the program will simply print a message and exit, but it may be exactly what you need!! It’s that simple.
Or you may prefer to print a message and return to the main user interface (command prompt, GUI, whatever). That’s easy to do. You just need to write code in the user interface (to show the message) and where the error occurred. You don’t need to write anything in-between. That’s how it happens in every language except Java.
But with Java’s checked exceptions, we are thrown back to the C style: at every damn function in the call stack we need to write code to either handle the exception or rethrow it. I repeat: at every damn function in the call stack. The decoupling between exception and handler doesn’t exist anymore.
If i had to write Java, i would use only RuntimeExceptions or would declare everything as “throws Exception”. This way, at least I know that I won’t ignore exceptions because I can’t handle them (those damned empty catch blocks).
June 7th, 2007 at 5:26 am
ikk,
Like a lot of people who vote against checked exceptions, you clearly are not comfortable with the Java language, and do not understand the proper way to use exceptions in this language.
One most certainly does not have handle and catch and rethrow exception you are not prepared to handle, regardless of whether it is checked or not. All you have to do is declare that your methods
throws FooExceptionand forget about it. The difference between this and what you propose is that in the Java approach recipients are warned about what might be coming out of a method. In your approach you have no idea what a method may throw.The only time you may get into a little bit of trouble is when you’re overriding a method that does not allow a checked exception to be thrown. This happens in frameworks sometimes, but in your own code it’s never a problem.
The only thing that makes me wonder if checked exceptions aren’t a good idea are the human interface issues. Clearly ten years in, there are still many, many programmers never got beyond
tryandcatchand never learned how to usethrowandthrows. I still tend to think the answer is education, not language change, because I think the underlying model is solid and much more solid than the alternatives. However sometimes when I’m looking at yet another code base where every single checked exception is immediately wrapped intry-catchwith no more than a cursory call toSystem.err.println, I do begin to wonder if maybe I’m overestimating the ability of the typical Java developer.June 7th, 2007 at 7:30 am
ERH, One of the points many people have brought up repeatedly is that even when you declare a checked exception in the method signature, you still have additional work in every caller, and its caller, and so on. Either the caller must handle it, or declare it in its method signature. This often leads to an unholy mess.
As to your comments about programmers not understanding how to use throw and throws, that is more fittingly addressed to the Java API designers, who screwed up big time. The vast majority of developers in any language community will tend to be thought-followers, not thought leaders. The vast majority of Java developers probably were not even aware that they were using checked exceptions until this debate started in the community about three years ago.
For anybody to blindly accepted everything given to us by the Sun “gods” is inappropriate, especially so for a thinking writer and professor . One of the key things that a University reaches (or should teach) is to question everything and be willing to admit ones mistakes and learn. Learning is a lifelong quest and never stops until the day one dies. Admitting and making mistakes is a part of the learning process. The Sun gods should be willing to admit that checked exceptions were a bad idea. Which is what they seem to be doing, but they are using closures as a covering for this.
The bottom line is that anything you can do using checked exceptions you can still do using unchecked exceptions, including declaring them. But there are things that can be done using unchecked exceptions that can’t be done using checked exceptions. Like letting the error propagate up the calling stack until a handler is found. So what particular benefit do checked exceptions give?
And that is precisely why no other language has checked exceptions, nor is there a need for them in any other language.
Java started off with checked exceptions, people got familiar with them, and refuse to see that other options are just as good, or better. The hardest part of learning new things is unlearning old things.
June 7th, 2007 at 7:34 am
Elliotte, you repeat the advice that launched me into this thread in the first place. So I repeat my question:
Say I have a nice domain-level API going, all types involved nicely expressed in the terms of the domain - say, the accounting domain, just to be innovative. I need an Accountant#retrieveClients method, and the implementation class uses, say, SQL (yep, another shocker there).
The Accountant is my own code. Should I just add a reference to SQLException to Accountant, and forget about it?
I’m really curious.
June 7th, 2007 at 8:07 am
Elliotte and others, we agree to disagree
I don’t like much CheckedExceptions for various reasons, and I believe removing them from the compiler does not mean removing them from the attention of the user. This last part is mostly ignored in those checked/unchecked debates, though it makes a big difference (see later in this post).
Due to the nature of most of the programs I write, 80% of the checked exceptions are for cases that cannot happen. In fact, I probably have more cases of RuntimeException that happen than the number of CheckedExceptions. Would the “CheckedException” advocates want to see NullPointerExceptions become Checked? That would not be too hard: “we just have to add a throws clause to the method signatures” of 80% of the Java APIs. And does that mean my code is not robust? Well no, because I handle those runtime exceptions. Bonus point: I can handle them at the logical level in the stack.
The compiler could issue a warning for CheckedExceptions if the method does not declare a throws clause or has no surrounding try/catch block. An @SuppressWarnings(”exception”) would remove this warning, but the user has to handle the exception. If the exception cannot happen in that context (like reflection on a known field of an application that has all access rights), just suppress the warning. No API rotting with a throws clause, nor an empty try/catch block.
As an analogy, let’s consider Generics (and no debates whether their implementation is good or bad, this is not the point). I am perfectly