http://harry.hchen1.com Harry has posted 1 posts at DZone. View Full User Profile

On Java Exception Handling

08.12.2008
| 22668 views |
  • submit to reddit

I came across a series of blog posts by Daniel Pietraru that deal with the use of exceptions in Java programming — I love it. The exception framework in Java provides a means for programs to signal and handle errors and other exceptional events. It’s not difficult to write code to throw and catch exceptions in Java. But, properly use exceptions in Java programs is not well understood by many developers.

There are three types of exceptions in Java: checked exceptions, unchecked exceptions and error exceptions. Checked exceptions are all exceptions that subclass from the java.lang.Exception class. When a method throws a checked exception (e.g., IOException), the client code must handle the exception by either defining a try-caught block or delay the exception handling by propagating the exception event up to a higher level code.

Unchecked exceptions are all exceptions that subclass from java.lang.RuntimeException. Unlike the checked exceptions, when a method throws unchecked exceptions, the client code is not required to define explicit code to handle the exceptions — e.g., NullPointerException.

Error exceptions, the last type of exceptions in Java, are all classes that subclass from java.lang.Error. These exceptions indicate serious problems that a reasonable application should not try to catch. For example, the exception java.lang.VirtualMachineError indicates the JVM is broken or has run out of resources necessary for it to continue operating. Developers rarely need to throw error exceptions or write codes to explicitly hand error exceptions.

When designing a Java API that throws exceptions, how should you choose to throw a checked exception and an unchecked exception? Daniel discussed this in Exceptional Java - Exception design relatively. Answers to this question is also described in Joshua Bloch’s Effective Java.

The basic guideline:

  • Throw checked exceptions if the problems can be reasonably recovered in the client code.
  • Throw unchecked exceptions to indicate programming errors (e.g., bugs in the client code and mistakes by a careless programmer).

Sometimes it’s difficult to draw a black-and-white between which exception to throw given a specific exceptional condition. It’s really up to the developers to decide. Exception handling in Java if use properly can greatly improve software quality. It’s definitely valuable for developers to think about exception handling design in an early stage of their software development cycle.

Published at DZone with permission of its author, Harry Chen.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Tarun Ramakrish... replied on Tue, 2008/08/12 - 8:21am

Java is unique in perhaps being the only language that provides checked exceptions.

Do people really bother using checked exceptions in Java anymore for new API's? I have completely stopped using the same.. I find checked exceptions just pollute interfaces and lead to greater problems when refactoring code. I think perhaps 1% of actual exceptions in use fit into the category of "checked exceptions" and it doesn't seem worth the trouble to make them checked.

Casper Bang replied on Tue, 2008/08/12 - 10:11am

I have to agree. It is not all all clear to me that checked exceptions make things easier. In the official JRE libraries they are used very inconsistantly and they make consuming API's verbose. I also believe they are a major factor to why getting closures into Java is such a pain (they have been added to most other language without much trouble).

But the single most annoying thing about checked exceptions, is how you are not allowed to catch them if you do not have code that throws them. So if you temporarily comment out a call to something which declares a checked exception, you now also have to comment out all the surrounding try...catch stuff. This is in spite of Java being capable of providing a "Unreachable code" warning in many other scenarios

Simon Martinelli replied on Tue, 2008/08/12 - 1:42pm

In my opinion the solution could be simple:

Use checked Exceptions only for business faults. They are part of the interface contract. 

But any other Exception thrown by JRE or any other framework should be derived from RuntimeException!

slow darkening replied on Tue, 2008/08/12 - 1:59pm

What's the alternative to checked exceptions? Return booleans or return codes? Is that better than checked exceptions? I hardly think so. It's true that many times exceptions aren't used as they should and that's indeed a disadvantage. However if used correctly checked exceptions can help your application to become bullet proof. Learn what and when to throw. Learn what and when to catch. Think before you write. Once you got it you will be a much better developer and your applications will be much more robust.

Casper Bang replied on Tue, 2008/08/12 - 2:36pm in response to: slow darkening

[quote=slowdarkening]Learn what and when to throw. Learn what and when to catch. Think before you write. Once you got it you will be a much better developer and your applications will much more robust.[/quote]

Herein lies the problem. Hardly anyone, even JDK authors, knows how to apply them correctly. Consequently most recent technolgies I know of avoid them altogether.

Exceptions should be used for exceptional cases only, putting handcuffs on the consumer of an API has many side effects. People will just wrap the call in an empty catch so they can move on and focus on the primary code path of their applciation, indeed as they should.

I can appreciate the theoretical bennefits of being able to see what can go wrong, document valid exit points. The fact of the matter is though, that much more can go wrong that what you are able to express with checked exceptions and it just doesn't scale. We all use powerful IDE's today which are more than capable of pointing these thigns out and at the end of the day, no amount of checked exceptions can guarentee the application works as intended, only your test cases can do that.

Joshua Bloch says about this, to only use checked exceptions for recoverable conditions. Recoverability however is somewhat subject to enterpretation, unless we talk about StackOverFlow or OutOfMemory kind of stuff.

phil swenson replied on Tue, 2008/08/12 - 2:55pm in response to: slow darkening

"What's the alternative to checked exceptions? Return booleans or return codes? Is that better than checked exceptions?"

 

No, use RuntimeExceptions.... just like every other programming language out there.

Checked exceptions are a failed experiment.  Almost every java project I've seen ends up deteriorating to either "throws exception" on every method or improper exception catching (empty catch blocks, or just logging exceptions and continuing) ...  this is the legacy of the Checked Exceptions...

Spring doesn't use them.

Scala doesn't

C# doesn't

Ruby doesn't

Groovy doesn't

Python doesn't

here's a good write up on the folly of Checked Exceptions:

http://www.mindview.net/Etc/Discussions/CheckedExceptions

Tarun Ramakrish... replied on Tue, 2008/08/12 - 4:45pm in response to: Simon Martinelli

[quote=webstyler]

In my opinion the solution could be simple:

Use checked Exceptions only for business faults. They are part of the interface contract. 

But any other Exception thrown by JRE or any other framework should be derived from RuntimeException!

[/quote]

Nice rule..but in practice defining what should be considered a "business fault" is not so easy especially when writing API code. For some clients of your API, it will be a business fault, for others it won't be a business fault. The clients who aren't concerned have to end up writing catch-wrap-and-rethrow blocks. And there is also the "implementor" viewpoint. Can you guarantee that _all_ possible implementations of your API will be checking and throwing this 'business fault' ?

If it satisfies all those conditions then yes its a checked exception! However, the intersection of all those sets is minimal tending to zero...

Simon Martinelli replied on Wed, 2008/08/13 - 2:36am

With business fault I mean really exceptions in a business method e.g. getCustomer(), findAccount(), doSomeStuffWithMyShoppingCart etc in an enterprise application with "normal" useres.

In APIs if they are technical nature all Exceptions should be RuntimeExceptions.

Jakob Jenkov replied on Wed, 2008/08/13 - 5:48am

In my experience checked exceptions get in the way more than they help. I've stopped using them. The only benefit from checked exceptions is that the compiler forces me to see them. No, not to *handle* them, but to *see* them. That's all. I can still just catch and ignore them. The downsides of checked exceptions are many though:

Developers are often fooled into believing that a method throwing a checked exception *only* throws that checked exception. In practice it may throw other unchecked exceptions though, which are then left unhandled.

Checked exceptions pollute interfaces and makes interface evolution harder.

Checked exceptions result in exception wrapping and a lot of ugly boiler plate code.

 But the checked vs. unchecked exception discussion is getting old. Even Anders Heilsberg and James Gosling has commented on this. I wrote up a small summary of the discussion some time ago, with links to relevant articles on the topic. It's found here:

 http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html

Casper Bang replied on Wed, 2008/08/13 - 6:29am

> Checked exceptions pollute interfaces and makes interface evolution harder.

Exactly. As anyone who tries to proxy an interface have struggled with.

I agree it's getting old, but I'm surpriced how many proponents there are left in Java. Many who are looking a little beyond have come to the realization that they are not really beneficial (Guido Van Rossom, Bruce Eckel to add to your list), but we don't really hear from many who are still in the Java camp. In fact, I just finished reading Jaroslav Tulach's (NetBeans) new book "API Design - Confessions of a Java framework architech" and in all it's practical advice there is not a single mentioning of checked excaptions. I can only draw one conclusion from that.

http://wiki.apidesign.org/wiki/Main_Page

Milind Rao replied on Wed, 2008/08/13 - 10:33am

I'm amazed at how many people think Checked Exceptions are bad! They are absolutely essential for building robust applications. If you are handling it by ignoring it, then you do so at your own peril. I almost never use Runtime Exceptions. I guess it's because I learnt OOP using an Eiffel-like language which heavily esposues design by contract. In fact, I wish there were Pre and Post conditions in Java.

Casper Bang replied on Wed, 2008/08/13 - 11:10am in response to: Milind Rao

The problem is not the contractual part, indeed I wish Java had pre and post conditions too. The problem is the handcuffs checked exceptions becomes when dictating the surroundings - which it knows nothing about. In this day and age, is there really a good reason for why javac and our IDE shouldn't just treat a missing catch of a checked exception as a warning condition? Much like we can enable warnings for many other things with the -Xlint argument (and override with an annotation). Seems to me that way you can have your cake and eat it too.

Milind Rao replied on Wed, 2008/08/13 - 11:32am in response to: Casper Bang

Can't say that I agree with that. An exception is just as integral a part of the contract as an argument. Not handling an exception is an error just as passing a String to a method accepting an Integer is an error. With checked exceptions, I know exactly the error that the method is going to throw. It's part of the contract. With runtime exceptions, I have to rely on documentation. If someone is going to handle checked exceptions by ignoring it, then frankly they are just shooting themselves in the foot. I wouldn't want to be debugging their code. They shouldn't want to be debugging their own code! But as someone said, this argument is old and everybody's already taken their stands on either side. I just continue to be amazed at how many people consider what I think is one of the best features of Java, to be some how hobnailing them.

phil swenson replied on Wed, 2008/08/13 - 11:36am

"If you are handling it by ignoring it, then you do so at your own peril"

 No one said handle by ignore.... with runtime exceptions, you let it bubble up to the proper place and handle it there.  Usually exceptions are from bugs or system problems and you can't do anything to recover.  If you hit a SQLException, it's usually either a bug (like a foreign key contraint violation) or a system problem (DB down).  There is nothing you can really do.  So ideally you let the exception bubble up to the top thread and alert the user, log it, email an alert, etc.  Of course it depends on the app/use case.

What I see with CheckedExceptions is in a complex system they become untenable.  It becomes such a pain to maintiain throws clauses that they all become "throws Exception".  This becomes the same as just using RuntimeExceptions.   This isn't so bad, but what I also see is people just do a "try{blahblah}catch(SQLExceptione ){Log(e)} and continue.  Usually this is NOT what you want.  It has the effect of hiding the exception from the user and they think that everything is cool.  90%+ of the time if you hit an exception, you have problems.  Logging and continuing the transaction has the effect of masking the problem and the bug/system problem doesn't get exposed and fixed.  Most people only look at the logs if they know there is a problem to begin with.

 I am being general here, I know there are cases that you would log and continue...

Part of the issue is the mentality that you can and should handle every error case.  This leads to bugs being masked and not fixed.  If a user enters an order and there is a sql exception and the order doesn't get saved, do you really want to continue as if everything is good and they should expect their order to be shipped?

slow darkening replied on Wed, 2008/08/13 - 1:44pm

I understand most of the arguments against checked exceptions but still I feel uncomfortable to accept that a helpful feature should be "thrown" away just because people misusage it.

My experience tells me that some component designs need checked exceptions and others don't. It's all in the nature of the component being written.

Checked exceptions are a good thing if used in the right places. They're actually alerting for a special category of problems. The ones that don't happen very often. The ones that developers usually don't care (because it's a pain) but sooner or later have to deal with and in the worst of the situations. In a production environment. Having a way to identify this problems while developing gives us a tremendous advantage. Using runtime exceptions doesn't gives us this power. Using runtime exceptions it's just telling the developer to be be sloppy.

I see downsides for both approaches. Who knows... perhaps a better one is still to be discovered.

Casper Bang replied on Wed, 2008/08/13 - 1:51pm in response to: slow darkening

[quote=slowdarkening]

I see downsides for both approaches. Who knows... perhaps a better one is still to be discovered.

[/quote]

That's the attitude C# took. I do find it interesting that more and more are starting to agree with this neutral position, even Java guro Neal Gafter:

"In practice, checked exceptions can result in API complexity, and programs appear to be cluttered with exception handling code just to satisfy the compiler. Some people believe checked exceptions are a good language feature but are misused, even in the JDK. With the "experts" being such poor role models, how can we expect ordinary Java programmers to do better?"

Milind Rao replied on Wed, 2008/08/13 - 2:23pm in response to: phil swenson

Who does this?  Logging an exception and continuing?  I have never seen people coding like this.  And if they do, then its an organization that needs to have extensive code reviews. 

The whole point of an exception is to think about how to handle it.  If the order didn't get saved, the user has to be notified that it didn't get  saved.  At what point are you going to do it?  Do you think the coders who can't be bothered to handle checked exceptions are going to handle Runtime Exceptions?  If you can pass in correct arguments to a method, you can handle exceptions.

What is so  difficult about figuring how to handle exceptions?  Either the caller can handle it or it can't.  If it can't, you clean up and pass on the exception.  If it can, you are better served with a checked exception since the compiler informs you about it.  I already have trouble with displaying errors to users from Runnable's run method since it doesn't throw a checked exception.  Imagine having to deal with this all over the code.

 I just find this whole debate inexplicable.

 

Jakob Jenkov replied on Wed, 2008/08/13 - 5:35pm

In reality (in my experience, that is), RuntimeExceptions do not cause the excessive dangers that checked exception evangelists foresee. Most of the time you will either just cancel the whole request (in HTTP requests or web service calls), catch the exception in a central place, and keep the app running for subsequent requests. No need to take down the whole web app just because a NullPointerException happens once in ten days. That'll get fixed in the next release.

Checked exception evangelists run around crying about all the bad things that can happen by not handling RuntimeExceptions. Well, at least an unhandled RuntimeException will make your application fail with a useful stacktrace. An inproperly handled exception forced by annoying checked exceptions won't. I used to be in favor of checked exceptions... because I had read in some book they were good. To date I have still not come across a single situation in which I was better off with a checked exception than an unchecked exception. There is no functional difference in the two. The only difference is that the compiler warns you of checked exceptions, and not of unchecked exceptions. But I can handle exceptions even if unchecked, so I don't need the compiler to tell me which of them I should and should not handle. In many app's it is just as important to handle unchecked exceptions in a sensible way as checked. And thus you end up having to handle both types anyways. Why bother with the checked exceptions at all then?

 

I think checked exception evangelists should stop talking and try building an app using just unchecked exceptions, and see what happens. Be a computer *scientist*, not an academic discussing theoretic problems. Then return to discussion threads like these with your findings *from reality*. Experiment and observe! Don't speculate. I tried doing that, and it convinced me I don't need checked exceptions.

Jakob Jenkov replied on Wed, 2008/08/13 - 5:37pm

> already have trouble with displaying errors to users from Runnable's run method since it doesn't throw a checked exception.

... which is a problem *caused by* checked exceptions, not *solved by*.

Milind Rao replied on Wed, 2008/08/13 - 10:38pm in response to: Jakob Jenkov

Try reading Bertrand Myer's, "Design by contract".  If you agree with that, then consider whether Exceptions should be considered as part of the contract or not.  If you don't, then you will prefer to use Runtime Exceptions.  If you do, then like me, you will realize that it produces roubust code.

Secondly, you talk about being able to handle Runtime Exceptions if you want to and ignoring it when you don't.  How many times have you handled a NumberFormatException while writing code the first time, without having got bitten when the number you expected turned out to be a string from a file?  Happened in the field?  Went back and fixed it?  Imagine doing that with all your code.  The biggest problem with Runtime Exceptions is that your entire code is filled with holes like this.

Our product has Java on the front end and C++ on the back end.  We run into a lot of problems because C++ doesn't have checked Exceptions.  The Java code does.  So been there.  Done that.  Got bitten by it.

Obviously, in this debate, it seems to be impossible to change anyone's minds.  So I'll make this my last post.

 

Milind Rao replied on Wed, 2008/08/13 - 10:38pm in response to: Jakob Jenkov

How so?

Jakob Jenkov replied on Wed, 2008/08/13 - 10:46pm

because run() does not declare any checked exceptions. that's why. But it could still throw RuntimeException's.

 About NumberFormatExceptions... I have code that could catch a NullPointerException too, in case the number string is null. No problem. Once you accept that RuntimeException's must be caught and handled too, this is no big deal.

D'Arcy Smith replied on Thu, 2008/08/14 - 3:06am

"Developers are often fooled into believing that a method throwing a checked exception *only* throws that checked exception. In practice it may throw other unchecked exceptions though, which are then left unhandled."

All unchecked exceptions should be left unhandled as they indicate programmer errors. Programmer errors are the sorts of things that the compiler would tell you about if it were able to (some things are not practical to check for, others are not possible as they depend on runtime conditions).

There are very few cases where production code should be trying to deal with unchecked exceptions.

If you properly use exceptions and perform proper testing then, unless you are doing something "odd" (like loading classes at runtime that are specified by the user) then runtime exceptions simply should not occur.

Of course this breaks if people start using runtime exceptions because they don't want to deal with the compiler implications of them. Once you do that your codebase is pretty much screwed though.

slow darkening replied on Thu, 2008/08/14 - 5:15am

By the way, the Exceptional Java - Exception design relatively referred in this post is a good example of how checked exceptions shouldn't be used (IMHO)... and why so many people end up hating them.

D'Arcy Smith replied on Thu, 2008/08/14 - 11:37am in response to: Jakob Jenkov

"I have code that could catch a NullPointerException too, in case the number string is null. No problem. Once you accept that RuntimeException's must be caught and handled too, this is no big deal."

You, as a developer, should make sure that you are not calling it with null. And if you put the tr/catch for the null pointer around more than a single line you run the risk of hiding other errors. All that because you don't want to write if(x != null)?!?!

If the system is coded properly, eg. RuntimeExceptions only being used for programmer errors, then there is no need to catch them. However once people start throwing things for non-programmer error the system breaks down and yes, in that code base, you have to resort to catching Throwable in a number of places. Having to do that means, very simply, that your codebase is broken (or you are loading code from 3rd parties where you don't have access to the source).

phil swenson replied on Thu, 2008/08/14 - 11:51am in response to: D'Arcy Smith

"Of course this breaks if people start using runtime exceptions because they don't want to deal with the compiler implications of them. Once you do that your codebase is pretty much screwed though."

so every system written in every other language than java is screwed?

D'Arcy Smith replied on Fri, 2008/08/15 - 10:40am

"so every system written in every other language than java is screwed"

looks around... nope I am still at javalobby or whatever it is now :-)

We are talking about exception handling in Java.  Specifically checked -vs- unchecked exception handling in Java.  What other languages do/do not do has little or no bearing on this topic.

And yes I have used other languages with other exception handling schemes.  I personally liked checked exceptions.

once you start introducing unchecked exceptions that need to be caught you have screwed your Java code base.

Casper Bang replied on Fri, 2008/08/15 - 11:12am

> We are talking about exception handling in Java.

lol If you are unwilling to compare to other practices and current state-of-the-art, then you might as well stop discussing these issues with the community.  I ask again, why not simply treat a "checked exception" as a warning condition? That way, prototyping (one extreme) can focus on the primary code path while mission critical implementatins (the other extreme) can treat every minute warning as a show stopper?

And remember, as good software developers we program into a language, not in a language. (Steve McConnel)

 

phil swenson replied on Fri, 2008/08/15 - 1:39pm in response to: D'Arcy Smith

"We are talking about exception handling in Java.  Specifically checked -vs- unchecked exception handling in Java.  What other languages do/do not do has little or no bearing on this topic."

 Sure it does since I and others are advocating using runtime exceptions instead of checked exceptions, following the model that pretty much every other language in existance uses.  If you think it would screw up your java code-base to do this then you are claiming that every project written in any other language is inherently screwed.

 Anyway, we clearly disagree.  You do it your way, and I'll do it my way :)

 

 

phil swenson replied on Fri, 2008/08/15 - 1:46pm in response to: Casper Bang

"ask again, why not simply treat a "checked exception" as a warning condition?"

Well, it's better than how it is now where you can't compile at all.  At my company we have a RuntimeExceptionAdapter class that we throw whenever we enconunter a Checked Exception that needs to propogate.  I'd prefer not to have to deal with warnings either as you try to keep your warning count to zero, otherwise you don't necessarily know you've introduced new warnings (one on the end of a list of 70 isn't noticable).  So if it were warnings, I'd want the option of turning that particular warning off.

I can't imagine Sun is going  to remove/change checked exceptions at this point.  However,  if Sun ever introduces a new language,I'd be very surprised if Checked Exceptions make the cut.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.