Saturday, May 26, 2007

Removing Language Features?

As a language grows by the addition of features, it necessarily gets more complex. After all, you can't remove existing language features because existing programs use those features, but each additional feature adds complexity. Right?

Fellow Googler Matt Shulman asked me a question about the Closures for Java specification. He observed that much of the complexity arises because of support for checked exceptions in the spec. Things like throws type parameters, disjunctive types, and throws clauses on function interfaces would be unnecessary without checked exceptions. Matt asked me if we had considered if things would be simpler without all that. At first I misunderstood his question to be referring to just the Closures specification, so I answered that the facility wouldn't fit into the language as well without support for checked exceptions.

Matt clarified that he was asking not just about removing support for checked exceptions from the Closures spec, but from the entire programming language.

There has been an ongoing debate on the utility of checked exceptions. Many people are critical of Java's checked exceptions, characterizing them as a failed experiment in software engineering. 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?

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.

This isn't a question I had thought much about. I believe the language could be simplified by treating all exception types as unchecked without breaking existing programs. This could also result in a simplification of future language extensions and APIs. But would the language and platform be better off without checked exceptions?

85 comments:

Stefan Schulz said...

I think that removing checked exceptions would be a feature and a benefit. At work, I tend to use unchecked exceptions more often than checked exceptions, as the latter cause much more work on refactoring, handling, or forwarding, which in most cases simply is unnecessary. Nevertheless, when explicitely throwing a RuntimeException, I declare the exception in the method signature and javadocs for visibility and explanation.
One problem I frequently have (and reading the debate links you gave, it seems common practice) is to forward exceptions without having to refactor the complete chain of methods up to the one, which handles the error. Wrapping exceptions every now and then is not far from dropping checked exceptions as a mechanism from the language. When developing a model, starting with some interfaces and so on, I usually don't care about possible exceptions the underlying implementation may or may not throw. Actually, often there different implementations of those interfaces throw distinct or no exceptions. Hence, either one thinks of all possible implementations (which is not very feasible) or "designs" new exceptions, the implementatations have to wrap theirs into. This makes it rather questionable, as the exceptions become more and more generic transporters of the original cause.
Of course, having checked exceptions one can force the caller to think about how to handle it, which raises perception of that there might go something wrong. Maybe, instead of requiring to handle checked exceptions by stating an error, the compiler could warn about uncaught "checked" exceptions. This would not break or raise any warning on existing code. Future code could either handle exceptions as before or treat them as runtime exceptions (of course with supporting a SuppressWarnings("uncaught") or the like).

Matthias Ernst said...

Number one on my list! All my ten thumbs up for that. And yes, especially closure proposal would benefit from it.

Anonymous said...

The Spring framework did it. You have no idea how some code in the wild looks like; people catching root exception and throwing six or seven specialized exceptions, or surrounding business logic with a variety of exceptions and then throwing Exception, or catching exceptions and then throwing error codes, or leaving catch blocks empty or catching NullPointerException

Ben Maurer said...

I think there might be a few interesting ways to deal with the pain of checked exceptions:

1. Make it a compiler flag. Some people just absolutely hate the feature, and for many people it just doesn't meet their needs. I've seen many students new to the java language frustrated at having to deal with the issue.

A compiler flag might be able to specify various levels of granularity (I don't care about the stupid IOException stuff, but MyDBException is interesting to me).

2. One interesting syntax would be:

class Foo throws IOException {

}

This means "anything in Foo can throw an IO exception". What's nice about this is:

1) It documents a general class contract, leaving room from future expansion (a method might not have been declared to throw something before, but an extension might be made in a future version)

2) it removes the cruft of doing the repetitive code

A huge con is that we'll see:

class X throws Exception
compiler flag, possibly off by default.
-Ben

Bob said...

Count me in.

Christian Plesner Hansen said...

I ran my own little crusade against checked exceptions a while back. I opened an RFE (#6376696) and discussed it with some of the relevant people at Sun. There was very little interest in doing anything about it and the RFE was ultimately closed as a "won't fix".

Hopefully they'll reconsider if someone like you brings this up. Checked exceptions just don't work.

Steven Brandt said...

Constantly having to re-wrap exceptions to match an interface is a real nuissance and does not, IMHO, add to code clarity.

I am not sure whether removing the need to check exceptions will increase or decrease the tendency to catch Exception, I can see it going either way. My guess is that it will lead to less frequent catching of Exception.

Henri said...

I suspect I'm in the minority of liking checked exceptions. To me it all feels like type safety - Java is a language with lots of type safety and checked exceptions are type safe errors.

When I'm writing in Perl or Ruby, I feel no need for checked exceptions. That's because I'm writing with a completely different style. If I want to write that kind of program in Java, then I'm quite able to add "throws Exception" to every method call; and will do for small script-like programs.

Contrary to one of the comments regarding bad habits in Exception coding (which will not change regardless of checked or unchecked exceptions); removing checked exceptions will encourage worse code as applications will simply fall over when something goes wrong. The libraries will have stopped encouraging developers to think about the consequences of an error.

Nico said...

Here's a posibility. As pointed in http://dev2dev.bea.com/pub/a/2006/11/effective-exceptions.html?page=2 , checked exceptions have their place. They should be used for "domain" exceptions.

Based on that.. why not do what Neal Gafter suggests, make all current exceptions "unchecked", and create a new marking interface called "CheckedException", which could then be used to mark (in new code) the exceptions that need to be checked. This interface would be used according to the new consensus about exception handling (it would be clearly documented how to use it in JavaDoc).

All exceptions would then be unchecked by default, and you would need to do something extra to mark one as checked. This marking could be an interface, and annotation or a common base class (the latter doesn't sound as a good idea).

D'Arcy said...

Good god no.

http://www.artima.com/intv/solid.html

I have exactly one unchecked exception that I use... NotImplementedError.

I did propose a while back an RFE for making all non-RuntimeExceptions that extend from Exception extend a new "CheckedException" class which would simplfy the code for people who really really don't want to deal with exceptions - just throws/catch CheckedException for all of it... unfortunatly it was rejected.

Robert Konigsberg said...

I too believe I'm in the minority; I like the idea about checked exceptions, because they help encourage the notion of throwing an exception appropriate to a domain.

More important, no checked exceptions encourages letting all exceptions propagate to the top of the thread's call stack.

I wish the language made it easier to deal with the process of wrapping exceptions of one type with another, since I hate to see people writing

void foo() {
try { bar(); }
catch(IOException e) {
throw new RuntimeException(e);
}
}

...
try {
foo();
} catch(RuntimeException(e)) {
...
}

since RuntimeException contains less information than IOException when making calls to foo().

Granted, this calls for a certain level of discipline; I would be happier with checked exceptions if this could be made easier, so people could properly use exceptions to begin with. So on possible way to re frame the question is, "What is in the way of making domain-specific exception handling easier?"

One recommendation, which I'm sure you've considered, is to make it easier to write classes that extend the exception hierarchy:

One way to do this is to eliminate the need to create pass-through constructors. e.g. eliminate most of the redundant code in

class SpecificDomainException extends GeneralDomainException {
public SpecificDomainException () { super(); }
public SpecificDomainException (String message) { super(message); }
public SpecificDomainException (Throwable cause) { super (cause); }
public SpecificDomainException (String mesage, Throwable cause) { super(message, cause); }
}

Wow, that's alot, particularly if you want to use a variety of domain-based exception classes. (and also if your team requires javadoc for every public method.) I'd love to see:

@ExtendConstructors
class SpecificDomainException extends GeneralDomainException {
}

And then I would create constructors all over the damn place.

I realize that particular annotation is flawed, but my point wasn't to misuse annotations, my point was to eliminate the constructors -- which there's just no way to do.

That's just one example.

Cedric said...

Count me firmly on the side of people who find checked exceptions very important to build API's on big code bases. Sure, they can be misused, but unchecked exceptions are being overused in a lot of places as well.

When I use a method from a library, I want to rely on the compiler to tell me what can go wrong, not on the documentation.

ahe said...

I don't think it would work to make it a compiler option (which is why I was in favor of closing RFE 6376696). However, turning checked exception compile-time errors into compile-time warnings makes a lot of sense to me.

Sam said...

I'm also in the minority of liking checked exceptions.

A classic argument against checked exceptions (seen in this discussion) is that it is not possible to pass the checked exception higher up the API if you are writing to an interface and the checked exceptions are part of the implementation details. I don't see why unchecked exceptions (in the guts of the implementation) make it easier to deal with this. If anything, checked exceptions should be screaming "deal with me now, because everything higher up won't be expecting anything unusual". RuntimeException tends to get caught too high up in the chain (if they are even caught) for recovery to be possible.

In case it hasn't been mentioned yet, Bruce Eckel’s ExceptionAdapter is useful for turning checked into unchecked. I've been meaning to chart our use of this wrapper, to see when checked exceptions start to become a burden. I suspect the answer would be when the exception is actually an Error.

I would argue that checked exceptions should be used for recoverable situations (i.e. the cause of the exception is obvious, and the client should be able to retry or report it in a meaningful way to the user without resulting in killing the application) or more controversially, as an alternative to returning null when the null can mean many different things.

Tim O'Brien said...

I think we need an annotation that would allow us to automate the wrapping of checked exceptions with Runtime.

Robert Konigsberg said...

Oops: slight correct to the bottom of my comment: I wouldn't "create constructors all over the damn place", I meant that I would create exception classes everywhere, what with the heavy work taken care of for me.

paulk said...

I think checked exceptions are useful. I discourage people from using them in generic libraries (because you are forcing your preferred style of exception handling on to your users) but encourage them in domain-level application classes. You need to be careful though because when you refactor, you can easily change some application-level code into a library. With current tool support, it isn't too hard to fix this as you go.

When scripting, I tend to use Groovy which automatically converts checked exceptions into unchecked, so you can have friendly compact script code - though it still lets you specify checked exceptions if you need to for integration with existing APIs.

When using Java, we typically have IDE and library support to auto-create an auto-boundary for any library we use that has checked exceptions in it (including some of the built-in libraries). This allows us to easily write interaction-style mock-based tests even when using such libraries which are harder to write otherwise.

So, I think the reality is that we have moved a long way from the early days when checked exceptions made our lives difficult and a lot of the initial push back on checked exceptions was common.

The fact that Java has checked exceptions is I think one of its strengths compared to C# (I haven't checked whether C# 3.0 adds this feature in).

So, I guess I wouldn't be in favour of removing them. Still keen for exploring ways to simplify Closures for Java though.

Anonymous said...

i will just add that in jdk you could easy change most of checked exception to unchecked, if IOException was unchecked now there will be no problem with legacy code :)

i think checked exception are usefull, but many times misused(when people think that every exception should be checked)

Anonymous said...

i will just add that I dont think its cool that will wrap it all in RuntimeException. RuntimeException could be also NullPointer or many other programming errors, i think that in jdk (because outside jdk i dont think people will do it) and make WrapperException that will just extend RuntimeException and than on theend you would know what is wrapped.

Chris said...

A C++ library is only usable from C++. But a Java library is usable from Java, Ruby, Python, Groovy and many others. Instead of trying to remove features from Java, just define your own new language and implement it on top of the JVM. If you can find a way to implement your language (IE modified java) on top of the JVM, then give feedback to the JVM guys to figure out what's missing. That seems like a better approach.

Neal Gafter said...

@Chris: checked exceptions are already absent from the VM, just as would be required for this change.

elizarov said...

I believe that so many people are against checked exceptions, because they don’t know how to use them properly. There is a clear lack of education about the power and the value of checked exceptions.
The other interesting observation is that people who criticize static type checking also tend to criticize checked exceptions. And vice versa, people who just criticize checked exceptions may not fully understand why anybody needs to declare argument and return types of methods. It is no wonder that a person writing in Perl does not understand what is the purpose of checked exceptions, since they tend not to realize fully the power of static type checking in general.
To realize why checked exceptions are so powerful it is educating to look at the mess that a big platform without checked exceptions becomes (.NET being a prime example). They unintentionally end up with APIs that throw exceptions that are not documented anywhere (since you cannot rely on documentation to properly reflect method behavior - compiler is not going to check verify your documentation). They also end up with complex software packages that just break on any I/O exception, for example. The programmer is not forced even to think what to do in a case of I/O exception. To continue I/O exception example (which is often cited by critics), I fully agree that reckless programmer will write a program that breaks on I/O exception even in a language that has checked exceptions. But it is not an intention of a language to completely prevent bad programs to be written (which is simply impossible in Turing-complete language), but to facilitate creation of good programs.
I, for one, have come to believe though practice that checked exceptions is one such facilitating mechanism that, in addition to other static type checking facilities, leads to our ability to crease very complex software with high quality for a reasonable cost. And I believe we need more static type checking facilities, not less! Every piece of our method documentation (like return types, exceptions, nullness, etc) that we can have our compiler to check for us is a win in our battle with software complexity.

Georgi said...

I came from Delphi to Java and was pretty much annoyed about checked exceptions in the summer of '99. WTF were checked exceptions all about, why did I have to catch them? That's only making my code more verbose with no use for me at all.
Well, times changed and my understanding of the Java exception handling did too. Fortunately. Today I use i.e. the "throws"-clause in method declaration pretty much by instinct, but it boils down (mostly) to one kind of usage: The moment the method you are writing cannot (logically) deal with the error that is thrown you need a checked exception to handle this behaviour in the calling peace of code. And you should do this checked, because the programmer using this method should be very clearly aware of that state.
IOException is a good example for this: You wrote a method to load something from the file system and, because of an unexpected error, it cannot proceed. In normal cases you might want to call this method from more than only one place (open-file-dialog, as a helper method etc.). So you cannot guarantee the usage of the method in itself and therefor not react in a proper manner (i.e. showing an error dialog - you do not know if the user triggered it and wants to see the dialog or if an internal call just happened to go wrong). That is the time for checked exceptions: The compiler encourages you to use the method accordingly, never mind from where you call it.

Just my 0,02 cents

Ricky Clarkson said...

I think that there's another way - making checked exceptions optional, through a new 'throws'-like clause. I've blogged about it here

Myron said...

Checked exceptions are an important part of why I joined the Java crowd.

Java's main focus is that it should be easier to read than to write. This is due to the 20/80 rule where 20% of the cost is in development, 80% in maintenance.

I like Java's focus. It has made me more productive for the larger programs. When I write simple programs, I can drop into Python.

Java's problem is not the language, it's the API. While it is a good API, there are problem areas, especially with consistency and deep hierarchies. Swing comes to mind but that is not the only case.

I believe closures will be beneficial to the language but not at the expense of removing contract checks. I would love it if the Java language was enhanced with Design By Contract mechanisms and additional restrictions such as const references (where the state of the class cannot be modified; thus making it a read-only version of the instance).

I believe Java is a unique language as it is focused on correctness, rather than "quick-and-dirty". When I wrote a large program in Python, with all the type asserts and checking, it would have been easier to produce the same code in Java, faster and better.

There are many language features that can be added without sacrificing static type checking:

Array slices
Tuples
Format strings (like in python "Blah %s" % "value")
Structs (value types)

If you look at the D language, there are quite a few ideas that can be adopted by Java.

I'm undecided on operator overloading in Java. Used correctly, it enhances the readability of the code. I wonder if there is a way to add operator overloading but mitigating the problems?

Lastly, I wish Sun would clean up the API, replacing deep hierarchies with composition, using exceptions that provide more details to the program (a message is useless for fault recovery logic) and simplifying.

Regards,

Myron.

Anonymous said...

Seems, some people see checked exceptions just as a nuisance, coming from called methods from some API. That makes me wonder, how they signal problems in their code to upper layers.
With some 'special' return value?
throw new Error() for everything??
Or just dont bother for the reasons and throw nothing at all???
Checked exceptions force you to decide: handle here or pass up.
Unchecked exceptions have too much of 'i just dont want to care...'

Tom Palmer said...

I almost hate programming in Java because of checked exceptions. It's the number one feature of every other language with unchecked exceptions (which means just about every other language). For instance, closures are vital but unchecked exceptions would be way more super bang for the buck.

Laird said...

Please leave checked exceptions in the language. They are often the only way to communicate richer details about a failure condition all the way up through the layer stack. That is, it's not just that the database went kerflooey, but that it went kerflooey during a particular transaction, which was initiated from layer X instead of layer Y. Having this archaeological sandwich is extremely helpful when you're called at three o'-clock in the morning with an urgent problem to fix.

Anonymous said...

Why we need Checked Exceptions: I start using a new library...how do I know what can go wrong with a method call? Rely upon the documentation? Dream on!

I've worked in C# and found it a very unnerving experience not knowing what could go wrong.

People like Unchecked Exceptions because it means they don't have to think about error handling. Thinking about error handling is a *good* thing!

Matt Shulman said...

Let's be careful not to confuse checked exceptions with exception chaining. (Exception chaining is the ability to catch an exception, and then throw a new exception linked to the causing exception, but with additional information.) Exception chaining is useful in places where you actually have more context about what operation was being attempted and you want to pass this up the stack.
Exception chaining applies equally to checked and unchecked exceptions.
Removing checked exception does not mean removing the ability to do exception chaining. Removing checked exceptions means we aren't forced to do silly exception chaining all over the place just to satisfy the compiler.

Tom Palmer said...

Laird, stack traces are how you know where a problem is (except when depending more heavily on dynamic circumstances). Exception wrapping a la checked exceptions just makes stack traces harder to read (or in some bad cases, not available at all).

Tom Palmer said...

Right on, Matt.

aehrenr said...

Dear Mr Gafter,
Java is mature in its features, very useful and successful. Its maturity is also the reason why you and others run in so many intricate special cases when you try to extend the language. Therefore I would suggest to leave Java (language) more or less as it is. Maybe a little tweaking here and there, so e.g. as a mechanism of closure implementation I would strongly opt for the CICE.
Of course there must be progress, but I simply question the strategy to bolt 1001 pet features on trusted old Java (language). Instead, the whole architecture of Java suggests a different, much cleaner and democratic strategy:
Implement a new language on top of the JVM !!! For now lets call it JavaNG. It should be close enough to Java so that it is very easy for developers to switch while conserving acquired know-how. It should also integrate very well with "classic" Java, just like Groovy as a scripting language demonstrates. But JavaNG should implement progress in a well designed and consistent way. Of course the exact features should be worked out by specialists like you, Mr. Gosling, Mr. Bloch and others but JavaNG could eventually do away with the distinction of primitive and object types, with array types (use collection classes instead) maybe with checked exceptions. It could have clean integration of closures, properties, improvements on the implementation of multithreading and other good ideas. Specification and implementation of JavaNG with all the experience from "classic" Java should be fun for language freaks like you. Heck, without the burden of backward compatibility of the code JavaNG could be even cleaner and simpler to read than "classic" Java. Then test JavaNG in the wild, make big PR (as with Ruby) and if everything is well designed, the big mass of developers will switch (this I meant by more democratic). Maybe you could support this migration by providing a "classic" Java to JavaNG compiler. Please think about this, before going on over-engineering "classic" Java and forcing the mass of developers to swallow it by integrating it in the next JDK.

Marko van Dooren said...

Hello all,

You might be interested in reading my OOPSLA 2005 paper about reducing the problems with checked exceptions:

my publications page

Sorry I don't have the time to explain the idea here, as I have to prepare my PhD defense for next week.

Regards,

Marko

Michel Ishizuka said...

I think the checked exception is mistake, but I'm afraid removing checked exception may cause another mistake.

in some cases catch clause will get unexpected exceptions.

Builder builder = .....;
try{
 builder.setFile(new RandomAccessFile("fname", "rw"));
 Runnable runnable = builder.newRunnable();
 runnable.run();
}catch(IOException exception){
 //old code: FileNotFoundException only.
 //after remove checked exception:
 // can another kind of IOException
}

in JDK1.1, new RandomAccessFile(String,String) can throw IOException.

I think, (a part of?/entire?) API should keep old style for compatibility. we can not remove checked exception completely.

Charles said...
This comment has been removed by the author.
Anonymous said...

Whilst I can see the argument here I don't think closures are worth ditching checked exceptions for. I don't see the complexity problem arise with the CICE closures proposal, so why not do this and explore the automatic resource management block proposal (http://docs.google.com/View?docid=dffxznxr_1nmsqkz)?

Checked exceptions always make me think of Churchill on democracy "democracy is the worst form of government except all the others that have been tried."

I really do think removing checked exceptions from the language would be a disaster. They are pretty key to what makes Java code generally so robust and no-one has yet come up with anything better (removing them isn't better, as anyone who has worked with C# and Java cal tell you). The biggest mistake in the Java exception model, in my view, is having runtime exceptions. How many times have you had to find a problem in an app that came down to a wretched nullPointerException that some dev hasn't dealt with?

gosha said...

Hi Neal,

After reading your "Java Puzzlers" book, I was so impressed (and partially frustrated too) with so many cavities and pitfalls in Java language (that seemed to me so rock-solid and elegant before the book) that I started wondering why nobody want to "fix java" by making new&fixed java-based language (I know, I know, stupid thoughts :) to implement all the suggestions from the book on how to improve the language (I believe there're much more).

Now when we hear more voices about the same problems and more (closures in particular) may be it's time to ask the question of a new java-like language again?

Neal Gafter said...

@gosha: certainly the community should work toward new languages for the Java platform. I consider Scala a strong contendor for Java++. However, that doesn't mean the Java language itself should stagnate.

Chris Smith said...

I am convinced that removing checked exceptions from Java would be a huge mistake. We already have (and it's not going to change) a language which is very exception-happy in its standard library design. The one saving grace with the existing standard library is the existence of a universal way to find out what may go wrong and deal with it. I've done my time with environments where random failures are expected in new code, and it's not good. I've done my time in environments where one must review every letter of documentation on pain of massive headaches before writing the first line of code, and I'd rather not return there.

If one is terribly concerned about the effort of maintaining information about checked exceptions, then it would be reasonable to add some kind of limited inference, so long as the information is made sufficiently visible by development tools; but certainly not to remove the feature entirely.

I realize this doesn't help simplify the closures proposal, but that's too bad. The closures proposal is solving a complex problem here, and complexity is to be expected. Giving up is not a solution.

Mehdi said...

Removing exceptions will not effect existing programs but will result in problems similar to C#'s. I really love checked exceptions because they force good programming skills. To prevent errors you should not avoid them you should make them impossible.

Mehdi said...

As far as JVM does not pay attention to checked exceptions, you can add a switch to java compiler to whether or not use checked exception, instead of removing it entirely from language.

fux11 said...

elizarov i absolutely agree with you. we need more checking. if you dont want checked exceptions go to c#. i am chief of developers in my company an we have some .net and mostly java projects. checked exceptions make the java-projects far more stable and the error-handling is far better. you cannot trust documentation, the compiler has to force exception handling. i also agree with the comment about all the perl ruby etc. programmers who try to change features of java because the DONT UNDERSTAND them.

Anonymous said...

I think that removing checked exception is a benefit. I think that DbC (Design by Contract) should be great benefit if this feature is included in the language.

paulo said...

I would much prefer if you removed apis from the language. Deprecate horrible API into another jar, and make them right. The text package ... the horror... the horror.

Doug Erickson said...

Mehdi's right on target. Obviously, checked exceptions are great. Maybe some people would benefit from more nuanced ways of responding to them. In addition to a compiler switch to toggle the behavior, a case-by-case annotation would be nice.

Anonymous said...

I have to vote in favor of checked exceptions.

Java promotes type safety. The throws clause clearly indicates the error states of the API (this is a good thing). And it forces you to think about errors (another good thing).

I rather have checked exceptions than closures! I'm happy with annonymous classes already. Could be better .. but oh well.

Anonymous said...

Of all the places I would have thought I wouldn't have to defend checked exceptions was here.

First, checked exceptions are especially useful in business logic. It replaces Return-Codes with a very descriptive name. And yes, makes you aware of the likely errors in business logic.

2) Here's some Irony: Microsoft recommends ignoring IOException. Problem: It occurs most often in windows. Writing to a log file failure, because the admin, in windows, isn't using Unix Command: TAIL to monitor a log file, but, has opened it in a text editor. Does your process END because a bonehead has opened your log file? or do you CONTINUE PROCESSING and create a new version?

My bias is for Checked Exceptions and my opinion is they are for Professionals.

Anonymous said...

Just like many other languages that are popular/powerful -- Java gives you the power to hang yourself. That does not mean you should remove the power. C lets some awful stuff go on, if you choose. The comment about liking exceptions is quite good. That's why we get paid to think and create a good piece of software that solves the problem at hand. Maybe the solution is to use another tool for the problem. That might be better than trying to 'fix' the tool for everyone.

I did enjoy the article and agree there are some bad uses of exceptions. I just think some people wish to dictate how everyone should construct software. Rarely do they know how EVERYONE uses it... I think we should keep them. We should just *refine* how we choose to use them - when appropriate.

Anonymous said...

I don't understand what is the problem with checked exceptions at all. What is bad about the language letting you know about possible errors that need to be handled? What are you proposing, that those errors are optionally not handled? Why would anyone want to do that? What's the purpose? And what's so difficult about using a try/catch or put a throws clause at the method name (nowadays done automatically by the IDEs)? What's the problem about creating custom exceptions for specific domains inside of the application for inter-communication and external use, and use the standard exceptions freely inside of the code letting them pass through the methods, only catching them where necessary? This makes me worrisome about the future of Java as a viable platform, it is a sign that the people designing it have no idea whatsoever of what they are doing and are just seeing who screams the loudest in order to decide what to do. Whoever uses only "unchecked exceptions" as a "workaround" or believe that needs to catch every single Exception just to throw it again (?) has a problem that would be easily fixable by learning Java in the first place, not changing the language.

frederic barachant said...

Removeing checked exceptions would be a mistake.
Java does a neat job in helping us produce quality code. Removing checked exception will lessen that ability and create more harm than it would solve. It was there for a good reason and has to stay.
Java does not have to be the next c#.

We must not leverage features of the language to accomodate the legions of sloppy developers of the world.
Java HAS to stay a quality enhancer to keep on being a winner. Projects are getting bigger and include more and more parts from outside. Programs are getting more heterogenous than they ever were and it will not stop. I for one do not want to learn docs from all APIS i use in order to know what exception each and every bit can throw. Compiler is there for taking care of this and it is PERFECT.

See people on .net side ranting and watch people here. Cheched exceptions bother few people, most do not care and accepted the fact. I mean, most are fine with it why would you want to change that?

Werner said...

Removing checked exceptions would be very useful. I have found them a nuisance esp. on bigger projects. Usually, they get wrapped inside unchecked exceptions.

Checked exceptions are a real pain for developing and using libraries since they must be declared when propagated or wrapped.

I also dislike the way that RemoteException is checked which makes EJB interfaces harder to use. The semantics of checked vs unchecked exceptions in EJB are also a pain.

In almost all my projects, exceptions are not handled until the GUI layer because in most cases I can't do anything about it; my motto for exception handling is: fail asap, don't undo, code ACID-ly.

You can still declare that a method throws certain exceptions; it's just that this optional for unchecked ones. I think most people like to see exceptions documented.

It would also be useful that certain methods that release resources are guaranteed not to throw exceptions. Java has made a real mess here (finally blocks that have try-catches inside, arrrggg).

The C++ community has thought better about exceptions, guarantees and safety patterns.

marius said...

Totally agree with Cedric and many others here that checked exception are quite valuable. Just because people abuse them it doesn't mean that the language should remove them. People abuse many other things from a language but this doesn't mean that the language is flawed.

Edson said...

We develop systems using Java and .NET.
We deal with checked exceptions encapsulating them in a framework exception (ugly but documented); but exceptions in .NET are totally undocumented (the Microsoft API does not document all possible exceptions, neither our programmers) and we have very big headaches with unexpected exceptions found in production phase.
We desperately need checked exceptions in .NET; don't remove checked exceptions from Java.

Anonymous said...

Many seem to think that checked exceptions make their code more reliable, which (in Java) is untrue. Error and RuntimeException subclasses allow unexpected exceptions to be thrown at anytime. Throws clauses can be changed, added, or removed without affecting binary compatibility. Therefore, catching all checked exceptions that can be discovered at compile time does not mean your code is robust.

I'm not even sure stronger enforcement of checked exceptions could improve things. Different subclasses of an exception could indicate completely different problems requiring completely different handling strategies. Therefore, catching a common superclass can not, in general, provide appropriate exception handling. Catching individual subclasses permits handling those cases individually, but new subclasses may not get appropriate handling. Constraining a method to throw only one, specific exception class only obscures what happened. Adding more detail by chaining exceptions is really the same as subclassing. It's just more flexible because it uses composition instead of inheritance.

With checked exceptions, what you end up with is handling individual exceptions you know about and can do something intelligent about, and letting everything else produce a stack trace or some generic error message. That's the same thing you have to do with unchecked exceptions.

If we end up at the same place whether exceptions are checked or not, then I say do the simpler thing and drop checked exceptions.

martti vh said...

Ok ok this is fun. So to all the people who say "checked exceptions are good cause you can't trust the documentation", how can you trust that a method will declare to throw a checked exception for all possible error scenarios?! And if you do declare all the exceptions your methods can throw as checked exceptions, how can you know the caller isn't going to wrap them in a RuntimeException? I would remind you that Java allows you to declare methods to throw RuntimeExceptions.

The fact that folks at Microsoft made asses of themselves by not documenting exceptions on their APIs doesn't mean that .NET or C# has a problem. It means that developers at Microsoft have a problem. And nothing guarantees that Microsoft APIs would have declared checked exceptions had C# had them. They could have been wrapped just as they are being wrapped in Java.

Bottom line: Remove checked exceptions. No language construct will guarantee good error handling, only good developers can do that.

Anonymous said...

Yea, and remove strong typing as well. Remove all these warnings from the compiler. Also, deprecation warnings should be switched off. Who cares anyway? Also, let all data be strings.

Anonymous said...

It's interesting how some people mistakenly think that somehow checked exceptions provide "static typing". In reality checked exceptions do exactly the opposite. A checked excepiton is almost always wrapped in some other exception, so by the time it arrives at the exception handler the true exception type is buried under layers of junk. The ability to use static typing catch a particular type of exception is now gone. The only way to catch a particular type of exception is to catch all exceptions and then dynamically walk the exception chain.
So, in reality checked exceptions are much less type-safe than unchecked exceptions.

Anonymous said...

It does not make sense to remove checked exceptions.

Checked exceptions do NOT exists to guarantee something. They should be use such that a method MAY throw DOMAIN exceptions hence they can be handled upfront because compiler reminds you that. Typically applications need to gracefully recover when domain exceptions are thrown (i.e NotEnoughBudgetException - such exception should be handled and making it unckecked means that this exception can be propagated in layers that have nothing to do with "NotEnoughBudget" wich makes no sense whatsoever ).

I don't even know why we're debating this again. It is like this for years. Some people like them and see their value and some people don't.

thecoda said...

The general problem here seems to be that we have to competing viewpoints:

1. Checked exceptions are a very clean and effective way of documenting aspects of an API

2. Java is already far too verbose, checked exceptions are just another example of this, where many of these exceptions are things that can only really be reported, not handled.

Given that both perspectives are essentially about code clarity, I don't see why they need to be mutually exclusive. Having said this, there is a clear need for a way to reduce some of the excessive boilerplate code that checked exceptions seem to force upon us; there are 4 ways I've seen such exceptions dealt with, only the first of which was considered when designing the mechanism, the second was catered for with java 1.4:

1. The exception is caught, appropriate action is taken to retry the operation or to achieve it in a different fashion.

2. The exception is wrapped in a more domain specific exception (possibly unchecked) that can be dealt with further up the call stack.

Prior to the introduction of exception chaining, this lead to a nightmare when attempting to follow a stack trace, as it only went as deep as the point where the domain-specific exception was thrown and not to the true cause

3. The exception is caught, nothing is done with it.

I've seen this happen far too often amongst developers under far too much time pressure to simply get something out the door, this is Extremely Risky(tm)

4. The exception is simply re-declared all the way up the call stack, leading to higher level APIs being forced to declare tens of exceptions, or more generic exceptions.

2 and 4 above are the culprits when it comes to code verbosity, 3 is simply the result of developers rebelling against this unnecessary boilerplate that nobody really wants.

My Solution?

Add a new keyword to the language: rethrows

This would be used in a similar fashion to throws i.e.

public void someDaoMethod()
rethrows SqlException as AlternateException
{
/* do something */
}

If an SqlException occurs, this would then be rethrown as an AlternateException, using the most specific constructor from AlternateException that accepts an SqlException as it's sole argument.

This would eliminate the equivalent:

public void someDaoMethod()
throws AlternateException
{
try {
/* do something */
} catch(SqlException ex) {
throw new AlternateException(ex);
}
}

And is just as simple (and safe) as:

public void someDaoMethod()
throws SqlException
{
/* do something */
}

note how such a mechanism would work automatically for RuntimeException, which has a single-argument constructor that can accept a Throwable, and would therefore accept anything.

As an added benefit, It should also be relatively easy to add tooling to IDEs that can list all possible underlying exceptions in a method and potentially even generate the necessary code to "unwrap" exceptions and re-expose their causes for more explicit handling.

As an aside, I find it interesting how people confuse the concept of checked exceptions with that of declared exceptions. As an example of this, a function can declare that it throws an unchecked exception. It would be a simple change to have have the compiler then warn if such an exception is not caught, although this would not cause a build failure.

Krishnan said...

I don't see how checked exception can be removed at this stage. It is quite easy to turn off the compiler check as others have suggested. But non-checked exceptions (Runtime Exceptions) are generally treated as programming errors and hence the exception handler would handle them differently. For instance EJB's container code drops the bean instance if it throws runtime exception.

So even if the compiler does not check anymore, there is whole lot of runtime code out there which distinguishes between "application exceptions" and "runtime exceptions". I don't think this can be fixed easily.

Anonymous said...

Checked exceptions used to be my favourite feature of Java because it made you think of errors.

Now I'm all my heart against them. Here is why:

@Override
Something aMethod() {
try {
doSomethingFirst();
} catch (ThatCheckedExceptions ex) {
handleException(ex); // shows a message box and eats the exception
}
...
return ...;
}


Thats the source of many errors. Thank God we have NPE.

Anonymous said...

I'm very much in favor of checked exceptions. Making a truly robust system without them is very difficult : certain errors have to be handled! No matter what! However, checked exceptions have to be used properly. A lot of people don't, and Sun has provided very little guidance on this issue. Many programmers think they understand how to use exceptions, but really don't grasp the fundamental shift in strategies that is needed for programs larger than a few classes.

A big part of the problem is that the default Sun exception library is poorly designed. Why is RuntimeException, an unchecked exception, extending Exception, a checked exception? Checked exceptions should be used to handle faults that can't be prevented at compile-time and so must be handled. Runtime exceptions can always occur, and so should not be checked. So if I catch Exception, I catch all checked and unchecked exceptions whether I want to or not! I should have an easy way to just catch the checked exceptions and let unchecked exceptions pass on by. Currently, this requires a second catch clause.

As for people complaining about the use of exception wrapping: Exception wrapping is THE RIGHT WAY to enforce error conditions at subsystem boundaries! If your bank tells you that they have lost money from your account, they don't tell you that the info was lost due to a filing error by Joe Schmoe due to the fact that his wife died (a EmployeeSpouseFatality exception). They just tell you that the money was lost (a MoneyLostException, which optionally wraps the EmployeeSpouseFatality Exception)). You don't need to know, and shouldn't care, WHY money was lost -- all that you need to know is that the outer exception that was delivered to you from the bank indicated the problem from your point of view and what you can do about it (invoking the GetAnotherBank() handling routine). It would be inappropriate for the bank to deliver the EmployeeSpouseFatality Exception directly to you -- there's nothing you can do about the situation, and no way for you to anticipate it. The 'bank' interface which throws a much smaller number of 'checked' exceptions protects you from needing to know that detail. The wrapping exceptions that they DO throw should be only those that allow you to make necessary decisions about what to do with your account.

Most of the complaints I have seen against checked exceptions basically boil down to an unwillingness by people to consider wrapping their exceptions at subsystem boundaries properly, or handling error conditions at all. (hint: having a single 'catch' clause in function 'main()' is almost never the right way to handle failures deep in an application that needs to be reliable!)

Yes, it would be nice if errors just didn't have to be handled, and if all programs could simply crash if something went wrong. However, in real software applications, this just isn't an option. If I read from a file and can't read the data, I probably need to do something specific about that specific problem (e.g. by wrapping it with a more specific CantReadConfigFileException or a CantBackupDatabaseException, both of which probably need to be handled differently), not just fall back on some generic file-error default handling strategy!

With the above said, Java needs to handle propagation of exceptions outwards from generic methods and others more smoothly. Using the Visitor pattern can be painful, for instance, unless there is some way to specify that a method can throw any exception that the method of the object passed to it can throw. This can be gotten around to a certain point with 'class Visitor<T,E> { void aVisitMethod(T instance) throws E;}' but this breaks down when more than one exception base class is needed. There should be a way (as is, I notice, referenced in the most recent Closures spec) to specify that a generic type can specify a number of exception types and not just one.

Reinier Zwitserloot said...

AFAIK, Checked Exceptions are mostly a declared figment of the compiler's imagination. It is in theory possible in bytecode to throw a checked exception without a method to declare it. You can even pull this off sneakily with Class.newInstance() which can throw anything.

So let's make that an official language feature - the idea of declaring that a checked exception is to be thrown up the chain as usual, but that it isn't declared (and thus any callers don't need to neccessarily handle it).


Something like:

public static String utf8ToString(byte[] data) ignores UnsupportedEncodingException {
return new String(data, "UTF-8");
}

Note how it makes it a lot easier to work around a number of D'Oh! Moron! moments in the JDK - the few places where checked exceptions are thrown where you know for certain it can't happen.

You can then make a rule for e.g. closures that ALL checked exceptions are silently thrown up the chain. (ignores Throwable).

Anonymous said...

I agree that unchecked exceptions can be a pain, however I that that the throws signature should be compulsory, for any code which throws an exception.

Anonymous said...

Please stop saying that you're in the minority when you like checked exception.

YOU ARE NOT IN THE MINORITY because nobody can really measure it. Those who are annoyed are just vocal that's why it seems that they are the majority.

If you keep on saying that proponents of checked exceptions are in the minority, well, the jury might believe you and you wouldn't like what their decision on this issue will be.

Brian said...

I posted some comments on this over on my blog (tried to post them here, but blogger seemed to temporarily not recognize me): http://www.briangoetz.com/blog/?p=43

mike said...

YOU ARE NOT IN THE MINORITY

Actually you are. I NEVER seen anybody who could USE checked exceptions properly, not just PRETEND he/she understands them. Look at any java.net project's source code if you don't believe.

Checked exceptions are pretty much like threads--they require an altered state of mind to be understood. Most people can get into that state of mind, but as they get sober, they forget.

So please, have mercy, make them optional!

Anonymous said...

I think that checked exceptions, done right, are necessary to build robust software, but I also think that they greatly clutter code and make the “unadulterated” path difficult to see.

What if there was an IDE feature that allowed a user to hide exception-handling code. When the feature was turned on you wouldn't see throws clauses or try/catch blocks (or the code therein). You would be able to quickly understand what the code is meant to do. You could turn off the feature to see the exception-related code in all its glory.

bluke said...

One of the main problems with checked exceptions is that they are part of the API and then if you change your implementation and another exception or a different exception needs to be thrown your public API has changed with all that that means. To solve that problem you need to wrap all the exceptions in some generic exception which is passed up. In a multi-tier system low level exceptions need to be wrapped 3 or 4 or more times which is ridiculous.

Frederic Simon said...

Thanks for relaunching the debate on checked exceptions, and really hope a good solution will be found. I compiled the arguments I found in here and on other blogs here.

I love static type, I hate String based development and find it difficult to develop with scripting languages.
Still, I don't want checked exceptions...

Nick Radov said...

I discussed this issue with you in person at the SVJUG meeting after JavaOne. Here is my reason for agreeing that checked exceptions should be removed from the language. It related to defining custom implementation classes for interfaces defined in libraries.

Let's say I am writing an application that uses two third-party libraries ABC and XYZ. Library ABC contains an interface InterfaceA with a method signature "void doSomething()". In my application I need to define a class that implements InterfaceA, and so has a doSomething() method. But in the body of that method I have to call another method from library XYZ. That XYZ library method throws a checked exception, let's say ExceptionX. Now what do I do? I can't add a "throws ExceptionX" clause to the signature for the doSomething() method implementation as it would violate the interface.

To work around this language design flaw I have to define a new custom exception that extends RuntimeException and wraps around ExceptionX, let's call it RuntimeExceptionX. Then in every single one of my implementation methods I have to catch ExceptionX and rethrow it as RuntimeExceptionX. So we end up with bloated, pointless error-handling code just to bypass Java's checked exceptions. What a waste.

Neal Gafter said...

@Nick Radov: You're correct: if your intent is that any exception causes your program to crash, checked exceptions certainly do get in the way. On the other hand, if you want your programs to be robust, checked exceptions force you to think about how to handle exceptional cases. If the exception in library XYZ is one that the client (caller) can rarely if ever do something about, then it was a design error in library XYZ (not the language) to make that exception checked.

Matt Shulman said...

Suppose the intent is not to have the program crash, but rather to have an exception handler in a central place that handles whatever exceptions get thrown from various layers and libraries underneath. Handling exceptions centrally allows operations to abort cleanly, and makes it easy to do good logging. In most cases, this is the most robust way to build large systems.
Because of checked exceptions, it seems like there is no way to achieve this except by doing lots of exception wrapping in the manner that Nick Radov and others describe.

David said...

Please don't remove checked exceptions from the language... They may be misunderstood, but they - like everything - have their place. The real solution here may be to add the keyword nothrow and require closures to contain exceptions. It preserves the language, does not break future code, and simplifies their design process.

Anonymous said...

Then give me the ability to decide which exceptions are checked and which are unchecked when I compile the package containing main().

greggwon said...

The issue with checked exceptions, from my perspective, is that people don't consider extern, uncontrolled stimuli as being able to effect the execution of their software. The believe that the software will always be in control of all things that happen.

User supplied input to a program is one place that problems can be introduced. Network connections or other types of external data or communications paths are also problematic. In general, asynchronous activity can also be problematic. Do you want your software to indicate that 0 bytes were written when it writes to a socket closed by the other end, or throw an exception?

Any piece of software which accepts a reference to another piece of software, and than invokes that software, is creating the opportunity for it to be affected by "bugs" or "behaviors" of that software.

Checked exceptions should tell you that there is something happening which you need to account for. There is not a returned value that can describe the event etc.

I agree with Neal's comment earlier. If the issue is that an API/library is incorrectly using checked exceptions, than let's fix that issue rather than "fix" the language.

Axel Gross said...

I also agree with the people thinking checked exception have their use and making the compiler complain instead of enforcing their handling would be a good way to go. Those people who don't need checked exception would not have to clutter their source code with useless stuff, exceptions won't have to be wrapped for the purpose of making them unchecked (which is a pain and blurs the distinction between programming errors and application errors).

To complement that, an official annotation should be provided which would make the warning go away
(sth. like @UncheckCheckedException and @UncheckCheckedExceptions(@UncheckCheckedException(class=IOException)))
for package, class, method or invocation, so you choose granularity by yourself).
And it would be good, if there was a type to distinguish RuntimeException from another Exception (i.e. all checked exceptions extending CheckedException extends Exception), so suppressed ones (and those which escaped through java quirks) could be handled.

And concerning closures. I think would be good to have the possibility to add checked exceptions to their declaration and again produce warnings:
Connection #connect(URL type) throws ServerDoesntExist, HTTP404 conWithXs;
Connection #connect(URL type) conWithoutXs;
conWithoutXs = conWithXs; // would produce a warning

P Huber said...

I'm part of the minority, too. I want checked exceptions to stay around for another while.
I must admit that sometimes dealing with checked exceptions is a big pain for me, but is this "sometimes" and "for me" thing the only reason to drop them? I know other people who fought with checked exception but would never doubt there usefulness. And I know people that have made their peace with checked exceptions in that they use the feature in a sound manner, which includes that they've made some sort of a "using exception guide" within their teams. And voila - some of the most unproductive (and more or less neverending) discussions vanished (at least for those people) and gave space for productive work.

I sometimes thought about different areas of mathematics, that they are a real pain in the a...But did I ever imagine to remove these features from the far field of math 's just to make *me* feel better? No because I knwo that there are others who may tag those features with "the most beautiful math's ever invented"

And let me ask a question: What is coming next on the endless trail of "would be better"'s to make closure realy useful. Have you ever thought about that?

What is really completely disappointing about the discussion about closures and stuff is, that there is a sort of set of discussion-patterns, with names like
1.) "It disturbes me"...so it must disturb anyone
2.) "Compare it to the worst"
3.) "New feature is good not matter what"
4.) "Only think about technical matters"...and don't concider impact on day-to-day project work.

Peter Lawrey said...

In general I'm in favour of checked exceptions as I tend to write libraries and I want certain cases to be handled by the developer and I don't want to rely on them reading the documentation (every time it changes)
Checked exceptions can be inconvenient at times but I have found that careful use of mechanisms like Unsafe.rethrowException() allows you to treat checked exceptions as if they were unchecked.

try {
IOUtils.readFile(filename);
} catch(IOException e) {
LOG.debug(filename, e);
// throws the exception as if it were unchecked.
unsafe.rethrowException(e);
}

I don't do this often or lightly.

However, I think checked exceptions ensure a better contract between callers and callees.

Eddie said...

Having programmed in both C# and Java, and having had to write and maintain *large* codebases in both languages, I don't understand how one can expect to write and maintain a reliable project without checked exceptions. When I write in C#, I find that documentation (where it exists) is light on describing what exceptions may be thrown from a library method or under what condition. This means that programs fail unexpectedly during development and testing until you have, by luck or thorough testing, encountered the lion's share of the undeclared exceptions that may be thrown.

It would be a huge step backwards for Java to discard checked exceptions.

What would help, instead, would be for the Sun APIs to create some more generic exceptions. For example, ALL IO Exceptions extend from IOException. Why is there not a ReflectionException so that one can catch just ReflectionException instead of having to catch three or four individual exceptions when doing reflection? For example, both InstantiationException and IllegalAccessException could extend ReflectionException. This kind of exception hierarchy would greatly simplify programming where you care whether or not your request succeeded, but you don't care about the reason why not if it did not.

Martin Schlömer said...

I need checked exceptions. period.
I don't mind if it becomes an optional compiler feature or is only checked by my IDE, but i want to have to pay that extra bit of attention when i have to decide "do i want to handle this here or in the calling method"?

I have a hunch people asking for these safety features to be removed from Java are the same whining about having to write an anonymous class instead of a closure - the ones wanting to type less and get things done fast.

To my experience "fast" doesn't cut it with large projects. Because no matter how much planning you did, you will end up having to change things later. And in order to change things, you need to be able to understand the code and refactor it.
And that's where readability, safety mechanisms and explicitly named classes and methods come in.
Otherwise you might end up forgetting about catching those exceptions.
And don't get me started on the millions of ways that will make closures a pain to refactor.

Neal Gafter said...

@Martin: I'm not proposing to remove checked exceptions, so no problem there. However, I think you are misinformed that closures are mainly about making anonymous classes easier to type. I can understand how you might have gotten that impression given other "closures" proposals aimed at just that end. One of the major benefits of closures are their improved support for refactoring.

Matthew J said...

I have worked in many languages in the past, including c, c++, pascal, basic, cobol, assembly, and of course Java.

For many years I have been a troubleshooter, locating problem in various software.

One of the best features of Java is the Exception handling. It makes finding bugs a lot easier. To remove this feature from Java would be insane.

Java's strong use of type checking and exception handling makes it more difficult for the developer to make a mistake in the first place and ecourages a more structured way of writing.

It annoys me when I see code that just catches and ignores exceptions, at the very least they should be logged. Another annoying and very bad programming practice is to catch the exception, wrap it in a run time exception and rethrow it. It makes my life hell.

So please do not consider taking this powerful tool out of Java, I know from long experience that Programmers are generally lazy, or due to tight deadlines do not want to be bothered with them but it is always the people who have to maintain the software who suffer for it.

I do however agree with the argument that exceptions should be able to be rethrown or demoted to an un checked exception, but with a limit.

By a limit I mean it should be forced to be caught at the top of the stack. This still forces the developer to think about how to handle the exception but still handle it soemwhere. But it eliminates the need to add ten layers deep of throw statement.

One mayor problem of the uncaught thowable is in threads. The thread can die with no warning or no message and cause strange very difficult to debug problems. If anything I think all exceptions should be checked, at least at the top level of a thread.

akuhn said...

Thumps up!

Remove them!

...and provide a JSR 308 checker for all those exception masochists out there. Shall they get their pain, as long as we can program in freedom.