Opinion: The Eternal Debate on Checked Exceptions

Home

News: Opinion: The Eternal Debate on Checked Exceptions

  1. The June issue of JavaPro has an interesting article on Java exception handling called "Control Your Exceptions". Lately, there have been many discussions in Java community on when and how to use checked and unchecked exceptions rendering mainly two coalition camps: for and against unchecked exceptions. Author, Daniel F. Savarese, brings up interesting issues and clears up confusion that has proven to surface among java developers from time to time.
     
    You can read the article at Control Your Exceptions (http://www.fawcette.com/javapro/2003_06/magazine/columns/proshop).
     
    Here are some takeaway points of this article:
    Always throwing unchecked exceptions is akin to writing class methods with unknown return types.
     
    You should not throw unchecked exceptions because it keeps you from having to write try/catch blocks. At the same time, you should not reduce your throws clauses to throw java.lang.Exception just to avoid writing a long throws clause. Both of these practices are the result of laziness.
     
    Throwing an unchecked exception from inside a class library, especially without documenting or declaring it, has the potential to tear down an application. Class libraries should delegate the responsibility of how to handle an error to the application.
     
    Throwing an unchecked exception from application-specific code—that is, code that will not be reused in other applications—can make a lot of sense...
     
    Personally, I could not agree with the author more. One of the most common arguments that I hear in defense of throwing unchecked exceptions is that with checked exceptions code becomes less readable. Well, this opinion obviously proves either lack of real-life expertise, not knowing good programming techniques (some of which are described in the article), or pure laziness as it was pointed out in the article.
     
    Also, there have been discussions on whether RemoteException in EJB should be made unchecked. I think the article indirectly explains why RemoteException is a checked exception: simply because authors of the spec should not make any assumptions on whether networking errors will be recoverable or not within the scope of applications using it.

    What are your thoughts?
     
    Best regards,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET

    Editor's Comments

    Bruce Eckel has interesting comments and discussion at http://www.mindview.net/Etc/Discussions/CheckedExceptions

    Threaded Messages (113)

  2. <dmitriy>
    One of the most common arguments that I hear in defense of throwing unchecked exceptions is that with checked exceptions code becomes less readable. Well, this opinion obviously proves either lack of real-life expertise, not knowing good programming techniques (some of which are described in the article), or pure laziness as it was pointed out in the article.
    </dmitriy>
    This isn't an argument: it's an attack on people who hold a different view to yourself as being inexperienced, ignorant or lazy. Your category of the inexperienced, ignorant and lazy includes Bruce Eckel (the editor has added a link above), myself, the designers of C#, Joshua Bloch ("Item 41: Avoid unnecessary use of checked exceptions"), the designers of JDO and the Java collections API, the designers of TopLink (one of the more successful Java libraries)...I could go on.

    I don't mind arguing the point with you (as I've already done in a different thread), but I do mind you trying to belittle anyone who disagrees with you.

    Readability matters. When code is forced to catch fatal exceptions it can't handle that reduces readability for no value: an indication for unchecked exceptions. If most callers will be able to recover or should be forced to handle the condition, it's appropriate to use a checked exceptiion.

    Rod Johnson
  3. I am also of the opinion that too many checked exceptions can be a problem. I think the core libraries define a good set of checked exceptions, for example ClassNotFoundException and IOException. These are well known exceptions that you can code meaningful catch blocks for. If you catch an IOException, you can ask the user if his network cable is unplugged!

    However, when an applicaiton or non-core library comes along with a large number of new exception classes, it becomes difficult to code meaningful responses to those exceptions. Most of the time you wind up treating such exceptions as "internal exceptions" because there is no way to propagate a meaningful action to the user of the software. These exceptions are useful to the *developer* as he debugs his application, but are typically no more or less useful than a generic Exception with a well articulated message.

    I am a big fan of JDO's use of unchecked exceptions.
  4. Rod, I am sorry if I offended anyone, that certainly was not my goal. I am certainly not trying to launch an attack on any people, products, or specs listed in your reply. Some of them I think demonstrate proper use of unchecked exception, some of them... I don’t necessarily agree with ;-).

    I think (based on your book and replies in some threads) you and I agree that throwing java.lang.Exception demonstrates laziness. Independently of where you stand on checked/unchecked exception issue, I beleive we both can agree that throwing java.lang.Exception simply to reduce the amount of try/catch blocks is also misuse and laziness. I think majority of java community shares this opinion.

    The area where you and I disagree is how to solve the misuse pointed out above (and also described in the article). You advocate throwing unchecked exception and relying on documentation and testing to improve robustness. I, on the other hand, prefer applying various programming techniques to make the code with checked exceptions more readable and rely on compiler to improve robustness. I think that both opinions are quite common in Java community.

    I agree with you that readability does matter, but proper use of checked exceptions does not decrease readability in any way. And again, I am not against unchecked exceptions, and share author’s opinion that there are proper places for using them.

    Hope this clarifies a few things,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  5. Not so[ Go to top ]

    <dmitriy>
    I beleive we both can agree that throwing java.lang.Exception simply to reduce the amount of try/catch blocks is also misuse and laziness.
    </dmitriy>

    Why do you think so? If it's part of a broader architectural choice where error handling is handled in a different way than religious use of exceptions, then it's NOT misuse nor laziness. It may very well be an intelligent, well-founded reason for doing so. In fact, experienced programmers stay away from checked exceptions.

    As you may have suspected, I didn't think the article you pointed to was any good at all.

    Granted, there are technical arguments for and against checked execeptions, but from my company's experience C++'s and C#'s approach is in fact much, much better (no checked exceptions)

    The reasons are rather subtle, but also get quite obvious in large projects. The names of the problems are encapsulation, maintenance, bloat and, in some cases, performance.

    Without going into detail, we (and others - check google) have found that the *only* sensisble place to use checked exceptions is the very place you KNOW that the caller can take appropriate actions to rectify the abnormal program state (which is, after all, what exception signify.) But since you know what the appropriate action is, you don't really need checked exceptions after all.

    A little known problem with checked exceptions is that it breaks encaptulation as the software at hand evolves. To see why, consider a class that logs error. This class may offer public method such as "logError" and "logWarning", both throwing a FileException when logging fails. Now, in version 2 of this log class the implementation is changed so that it logs to a database instead and now the checked exception becomes DBError. At this point, all clients fail...
  6. Yes so ;-)[ Go to top ]

    <han>
    Granted, there are technical arguments for and against checked execeptions, but from my company's experience C++'s and C#'s approach is in fact much, much better (no checked exceptions)
    </han>

    Hm... We at Fitech also extensively work with C# and find that total lack of checked exceptions in C# is a big disadvantage of the language. Without getting into specifics, most of the C# methods throw multiple unchecked exceptions. Some exceptions represent bugs in the application, some - recoverable errors, and some exceptions are thrown in case of fatal errors. Keeping track of what exception was handled in which method with time becomes a huge headache. Fortunately, there is a product that allows you to create checked exceptions in C# which we extensively used in our development.

    <han>
    ...consider a class that logs error. This class may offer public method such as "logError" and "logWarning", both throwing a FileException when logging fails. Now, in version 2 of this log class the implementation is changed so that it logs to a database instead and now the checked exception becomes DBError. At this point, all clients fail...
    </han>

    Han, what you described is a classic case of misuse. Personally I don’t think that logging methods should throw any exception, but I will follow your train of thought. If I was to throw an exception from my loggin methods, I would create LogException class that would be thrown out by *logError* and *logWarning* methods. LogException would wrap any exception thrown by the underlying log destination. This way the log destination remains transparent and clients don’t break whenever log destination changes.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  7. please: attain balance[ Go to top ]

    I have to agree with Dmitriy that C# suffers from the lack of checked exceptions.

    OTOH, as stated before, the ability to declare checked exceptions does not mean that you need to use them for everything ;-)

    To put the conclusion into a single sentence: Checked exceptions are a very valuable tool when they are used intelligently, and an endemic poison when mishandled by a naive coder.

    Peace,

    Cameron Purdy
    Tangosol, Inc.
    Coherence: Easily share live data across a cluster!
  8. please: attain balance[ Go to top ]

    <cameron>
    I have to agree with Dmitriy that C# suffers from the lack of checked exceptions.

    OTOH, as stated before, the ability to declare checked exceptions does not mean that you need to use them for everything ;-)

    To put the conclusion into a single sentence: Checked exceptions are a very valuable tool when they are used intelligently, and an endemic poison when mishandled by a naive coder.
    </cameron>

    There is nothing that stops you in writing your own exceptions in C#. It do not forces caller to catch that exception. If you want, you can certainly catch the exception. So why is it necessary for compiler to force the caller to catch that exception(Checked exception is basically nothing but compiler forcing you to catch that exception). Python is other language which do not Forces the caller to catch the exception that is thrown. Again remember you can certainly catch it if you want. I think flexibility of either catching the exception or leaving it to runtime is to be left to programmer rather than compiler dictating those terms.
  9. Not so ;-)[ Go to top ]

    <dmitriy>
    Hm... We at Fitech also extensively work with C# and find that total lack of checked exceptions in C# is a big disadvantage of the language.
    </dmitriy>

    As I said before, there better ways to handle the area of concern than checked exceptions.

    <dmitriy>
    Han, what you described is a classic case of misuse. Personally I don’t think that logging methods should throw any exception, but I will follow your train of thought. If I was to throw an exception from my loggin methods, I would create LogException class that would be thrown out by *logError* and *logWarning* methods. LogException would wrap any exception thrown by the underlying log destination. This way the log destination remains transparent and clients don’t break whenever log destination changes.
    </dmitriy>

    Classic case of misuse... hmm, yes that's sort of why I gave the example. And your resolution is not a resolution because the moment you unwrap the exception, encapsulation breaks miserably.

    There are several solutions, which one you choose is highly dependent on your architectural choices. At any rate, checked exceptions is not one of them.

    -han
  10. Yes so ;-)[ Go to top ]

    I would argue that for Exception handling there are 'usually' only a few things you can do:

    1.) Ignore/Report. The method called didn't work, but was not critical to operation so we ignore it.
    2.) Abort/Report. The method called was critical and the program likely can not continue.
    3.) Try an alternative action. If there is more than one way to do the operation so if the one throws an exception try the next one and the next one and so on.

    That's about it right?

    In most cases all 3 can be accomplished using java.lang.Exception and knowing the context of the method call. If I call a method and get java.lang.Exception I know the method failed. In most cases that is all I need to know. I can then determine to do #1, #2, or #3 based on this information and my knowledge about what the method is supposed to do.

    You example about throwing WarningException and CriticalException for the logger means you are giving control of whether to do #1, #2, #3 to the Logger class being called. The Logger class has no business making these kinds of decisions and by throwing a specific exception like you suggest, that is what it is doing. Instead all we need to know is that the log method failed. The code that used the method can then determine what to do with that information (#1, #2, #3).
  11. Yes so ;-)[ Go to top ]

    Well, I expected many different opinions in this thread, but arguments for throwing java.lang.Exception directly, I must admit, came as a surprise.

    As the article points out:
    Always throwing unchecked exceptions is akin to writing class methods with unknown return types. Imagine how difficult it would be to write reliable and maintainable programs if you never knew what the return type of a method would be. Perhaps the right Java analogy is writing only methods that return java.lang.Object.

    Well, throwing java.lang.Exception directly falls into the same category. When you catch java.lang.Exception and handle it generically it means that your logic handles IllegalArgumentException and SqlException the same way, which is, to be polite, ...hm... not very common ;-)

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  12. Yes so ;-)[ Go to top ]

    Well it is only a few crazies like me that are talking about throwing java.lang.Exception and you should expect a few crazies in every group ;-) I would be interested in seeing the 'proper' way to do it if you have time. Here is an example for you that you can correct for me. I have an interface for executing named queries:

    public interface QueryManager {
       Map executeQuery(String name, Object parameters[]) throws Exception;
    }

    I have many different implementations to this interface (some DB, some network oriented, some file oriented). At first I was throwing QueryException, but after a while of using this interface and seeing how the exceptions were handled I changed it to java.lang.Exception. I think that you might argue I was on the right track the first time with the specific Exception? If so why?
  13. Yes so ;-)[ Go to top ]

    If nothing else..
    Give the pecularity of Java, where Exception is checked, but it's subtype RuntimeException isn't - and all others are, you have just forced all your clients to have try/catch block for everything, or even worse, add "throws Exception" to their signature.
    My opinion is similar to Cameron's. Checked exceptions can be really good if used carefully. Or if everything is made a checked exception, it can be a real hell. Unfortunately, a rather large part of java's standard libraries fall into this category.
    Most likely in your example you should be throwing runtime exception in the first place - and it should be a QueryException, so later in the chain someone can actually tell what happened.
    Regards,
    Vlad
  14. Good point vlad[ Go to top ]

    <vlad>
    My opinion is similar to Cameron's. Checked exceptions can be really good if used carefully. Or if everything is made a checked exception, it can be a real hell. Unfortunately, a rather large part of java's standard libraries fall into this category.
    </vlad>

    The standard library is hell in this sense, yes. To make things worse, a lot of the standard methods list a number of checked exceptions and in addition it throws exceptions that you can only know about from the documentation. Given this, the argument that checked exceptions makes for good documentation is plain wrong. In fact, it may give a false sense of security.

    Java's exception mechanism is rather broken, but the suggestion of making checked exceptions into a warning is a step in the right direction. This would be simple to implement and it wouldn't break existing software.
  15. Give the pecularity of Java, where Exception is checked, but it's subtype

    > RuntimeException isn't - and all others are, you have just forced all your
    > clients to have try/catch block for everything, or even worse, add "throws
    > Exception" to their signature.

    i agree that making RuntimeException (unchecked) be a subclass of Exception (checked) was a terrible decision. better to have them each be immediate children of Throwable, perhaps.

    consider a scenario such as java.lang.reflect.Method#invoke, where you really want to handle all of the advertised checked exceptions uniformly. if you write:

    try {
      // ... reflective invocation
    }
    catch ( Exception ex ) {
      // log it, whatever...
    }

    you've now trapped any unchecked exceptions that you may have wanted to let fly. so you end up writing:

    try {
      // ... reflective invocation
    }
    catch ( RuntimeException ex ) {
      throw ex;
    }
    catch ( Exception ex ) {
      // log it, whatever...
    }

    which looks just plain idiotic.

    i'd have liked to see as part of the language the ability to handle a specific set of types of exception in the same catch block:

    try {
      // ... reflective invocation
    }
    catch ( IllegalAccessException, InvocationTargetException ex ) {
      // log it, whatever...
    }

    the restriction being that the catch block can only manipulate ex via methods common to the types of exception named in the catch clause. maybe that's too awkward...haven't reasoned it through very thoroughly...
  16. Nope.[ Go to top ]

    <dmitriy>
    Well, throwing java.lang.Exception directly falls into the same category. When you catch java.lang.Exception and handle it generically it means that your logic handles IllegalArgumentException and SqlException the same way, which is, to be polite, ...hm... not very common ;-)
    </dmitriy>

    Of course it is. And you know what? In a huge class of situations it is outright smart to do it. The reason? Polymorpism. Abstraction. Generic code.

    This doesn't necessarily mean that java.lang.Exception should be the exception you handle, but some other abstraction of several sub-exception classes.

    Consider the following method, taken from the Java API doc:

    public Object invoke(Object obj,
                         Object[] args)
                  throws IllegalAccessException,
                         IllegalArgumentException,
                         InvocationTargetException

    Are you telling me that in every instance I should should handle all three exception clauses in a different manner? What if my client code is merely interested in success/failure. The way a caller would handle the situation differs greatly, but I routinely handle all three exception above as one abstraction: "reflection call failed" - hence handling the Exception class upon a call to invoke suffices.

    Handling a calls exception polymorphically is just as viable as handling a parameter polymorphically.

    So, given your example, handling IllegalArgumentException and SqlException the same way is plausible in a number of situations.

    The analogy with only returning only java.lang.Object is farfetched... it's simply not the same thing. Exceptions are about things that shouldn't happend; orthogonal to the functionality of your application.
  17. Nope.[ Go to top ]

    "The analogy with only returning only java.lang.Object is farfetched... it's simply not the same thing. Exceptions are about things that shouldn't happend; orthogonal to the functionality of your application. "

    There are many Java library methods which return java.lang.Object.

    Throwing unchecked exceptions is a type of method overloading. It is, in many cases, perfectly fine.
  18. <han>
    > public Object invoke(Object obj,
    > Object[] args)
    > throws IllegalAccessException,
    > IllegalArgumentException,
    > InvocationTargetException
    >
    > Are you telling me that in every instance I should should handle all
    >three exception clauses in a different manner?
    </han>

    Just throw specific, catch generic *if you choose to*.

    try {
       invoke(...);
    } catch (IllegalAccessException e) {
       System.out.println("It's an Illegal Access error!");
    } catch (IllegalArgumentException e) {
       System.out.println("It's an Illegal Argument error!");
    } catch (InvocationTargetException e) {
       System.out.println("It's a Invocation Target error!");
    } catch (Exception e) {
       System.out.println("It's a generic error!");
    }

    or

    try {
       invoke(...);
    } catch (Exception e) {
       System.out.println("It's a generic error!");
    }

    Pick the one you want/need!
  19. Yes so ;-)[ Go to top ]

    In many cases throwing a generic exception is fine, because the exception only used to indicate success or failure, in which case it doesn't matter what the specific exception is (it is like a boolean with a message attached). In my mind the only place where you really require specific expceptions is when you have an object with state that is manipulated externally and so external code needs to know the nature of the exception so that it can properly reset the state (close resources, etc).

    i.e.
    obj.initialize()
    obj.connect();
    obj.dostuff();
    obj.disconnect();

    There is an order dependence here. I am putting the burden on the outside world to keep track of state externally.

    In these cases I may need to know what went wrong so that I can clean it up.

    Since I dislike order dependent classes or classes that require external state tracking and I seldom write such classes (see example interface above) or that require outside code to keep track of state, I seldom have to tell the outside code why things went wrong. They just need to know that it didn't work and a developer can view the message to see why.
  20. Not so[ Go to top ]

    <quote>
    A little known problem with checked exceptions is that it breaks encaptulation as the software at hand evolves. To see why, consider a class that logs error. This class may offer public method such as "logError" and "logWarning", both throwing a FileException when logging fails. Now, in version 2 of this log class the implementation is changed so that it logs to a database instead and now the checked exception becomes DBError. At this point, all clients fail...
    </quote>

    I agree. When writing interfaces it is difficult (and I would argue bad practice) to throw specific exceptions, because you do not know all the possible exceptions an implementation might throw. In these situations what else can you do but throw a generic exception such as java.lang.Exception or your own generic wrapping Exception. AND If you are just throwing generic wrapping exception then what is the value of making up a new one for every interface? There is no added value that I can see. So one ends up using java.lang.Exception quite a lot, or so I have found anyway.
  21. Yes so ;-)[ Go to top ]

    <anick>
    ...If you are just throwing generic wrapping exception then what is the value of making up a new one for every interface?
    <anick>

    Well there are several ways to mitigate this problem one of which is to embed error codes into exceptions (used by SqlEexception in JDBC), another is to have various subclasses of the wrapper exception for every error condition. There is no best way; it depends on the project design and requirements. However, in many cases it is sufficient enough to provide one wrapper exception which will allow the caller to gracefully handle it.

    I agree that in many (not all) situations, API’s throwing multiple checked exceptions could be difficult to use and I attribute it to bad design decisions made for these API’s. But there are also well-designed API’s that throw multiple checked exceptions and JTA API may serve as an example.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  22. Agreed[ Go to top ]

    I was going to respond much the same: You provide the wrapper exception class and the implementors can sub-class it as necessary.
  23. Not so[ Go to top ]

    that the *only* sensisble place to use checked exceptions is the very place you >KNOW that the caller can take appropriate actions to rectify


    Knowing a caller of your code probably means that code base of the project is pretty small and the same developer who writes library later uses it.

    Working on a slightly bigger code base I cannot say who and how is going to use my middle code, although I develop with pretty good idea about possible/intended usage of my code.

    In my experience knowing about possible exceptions is proven to be very helpful and valuable.
    However I would say that proper use of checked Exceptions requires some shift in own mindset.
  24. Not so[ Go to top ]

    <quote>A little known problem with checked exceptions is that it breaks encaptulation as the software at hand evolves. To see why, consider a class that logs error. This class may offer public method such as "logError" and "logWarning", both throwing a FileException when logging fails. Now, in version 2 of this log class the implementation is changed so that it logs to a database instead and now the checked exception becomes DBError. At this point, all clients fail...
    </quote>

    Good example of bad design :).

    The interface should throw something like LogPersistenceException.
  25. Not Not So ;-)[ Go to top ]

    Konstantin: The interface should throw something like LogPersistenceException.

    No, the interface for a logger shouldn't throw anything. The implementation can throw a RuntimeException at its own peril, but even that is ludicrously inane, as a logger is just a logger is supposed to be a terminal not-supposed-to-heave-anything-back-over-the-wall component.

    Just imagine if the new keyword threw a checked exception!

    Peace,

    Cameron Purdy
    Tangosol, Inc.
    Coherence: Easily share live data across a cluster!
  26. Not Not So ;-)[ Go to top ]

    No, the interface for a logger shouldn't throw anything. The implementation can throw a RuntimeException at its own peril, but even that is ludicrously inane, as a logger is just a logger is supposed to be a terminal not-supposed-to-heave-anything-back-over-the-wall component.


    Yes yes we know this, so it was a bad example. No reason to be so pedantic. Pretend that is a UserManager class or something else like that instead ;-)
  27. Not Not So ;-)[ Go to top ]

    No, the interface for a logger shouldn't throw anything. The implementation can throw a RuntimeException at its own peril, but even that is ludicrously inane, as a logger is just a logger is supposed to be a terminal not-supposed-to-heave-anything-back-over-the-wall component.

    >

    IMO:
    1. I agree that throwing RuntimeException is insane.
    2. Checked exception (generic one like LogPersistenceException) in method like “logWarning” is appropriate because it allows user of the interface:
    - create a wrapper and ignore such exception id logging is optional;
    - or do something if the logging is extremely important (logging of business activities for instance );
  28. I disagree[ Go to top ]

    <quote>
    Good example of bad design :).

    The interface should throw something like LogPersistenceException.
    </quote>

    I disagree. How would the calling code be able to handle such exception?
    It can cope with an IOException and ask the user to insert an empty disk or,
    it can handle a DBException and retry the transaction, but how would this be possible with LogPersistenceException?
  29. Re: I disagree[ Go to top ]

    <gregor>
     <quote>
     The interface should throw something like LogPersistenceException.
     </quote>
    I disagree. How would the calling code be able to handle such exception?
    It can cope with an IOException and ask the user to insert an empty disk or,
    it can handle a DBException and retry the transaction, but how would this be possible with LogPersistenceException?
    </gregor>

    Why should the top level code have to know whether the logger was trying to use the disk or a DB - you are commiting the cardinal error of exposing implementation specifics in your interface...

    ... if you added a JMS logger implementation you would have to add a new exception to your interface! Exceptions should always try to match the functional intent of the method call - why should calling code need to know about DBs or disks or messaging or whatever - all it cares about is that it has called the log method to do some logging!!!

    (Actually logging is a bad example - if logging fails, you would want it recorded somewhere, but it would be unlikely that you would want to bother the end user with details of the problem, never in the case of a ServerSide application. If you were a user of a web site and the request failed because the server was complaining about a logging error, you would justifiably reckon that the designer(s) didn't know their job. So in a server context, the log method wouldn't actually throw any exceptions at all.)

    Hypothetically, though, if you were throwing a checked exception out of the log method, you would use a functionally informative LogFailedException, wrap the root Exception (IO or whatever), and insert some useful text to the exception description field ("Check disk..." for the IO failure, etc).

    However, in this case, I would make the exception unchecked (but still wrap the same information) - because you really (in the example of the desktop app say) want the exception to propagate straight up to the top level exception handler, where the information can be displayed to the user.

    The important question to ask is:

    "Can this error possibly occur in a correctly configured and running system, with no coding errors?"

    If it can then it is a checked exception (at least as far as the next code layer - ask the same question again there), if not it is unchecked. In this case the answer is clearly no (there is an unexpected failure beyond our control), so there is no point passing a checked exception to the calling code as it would not have the information to deal with it.


    It is not a coincidence that people seem to be moaning all the time about buggy code, and at the same time developers seem so unclear about their exception handling strategy.

    Good, reliable, code has exception strategies designed in from day one. Error handling is not something you think about at the last minute before you ship.

    /david
  30. Re: I disagree[ Go to top ]

    "Can this error possibly occur in a correctly configured and running system, with no coding errors? If it can then it is a checked exception..."

    No, no, no. If you expect an errornous situation in a bug-free application, then it's not an exception.

    The best advice I've seen regarding exception handling strategies is this: If you take out all the exception handling code in your application on a sunny day, will your application still run? If the answer is no you have a problem.
  31. Re: I disagree[ Go to top ]

    <han>
     "Can this error possibly occur in a correctly configured and running system, with no coding errors? If it can then it is a checked exception..."
    No, no, no. If you expect an errornous situation in a bug-free application, then it's not an exception.
    </han>

    I suggest you read something like the RUP (Rational Unified Process): They talk quite clearly about "Standard Flows" (normal program execution) and "Exceptional Flows" (expected flows handling possible known errors).

    E.g. NumberFormatException. You know that data input from a user may be invalid and needs validating and cleansing before being allowed into the system. This is an entirely expected exceptional flow.

    <han>
    The best advice I've seen regarding exception handling strategies is this: If you take out all the exception handling code in your application on a sunny day, will your application still run? If the answer is no you have a problem.
    </han>

    Oh dear.

    /david
  32. Re: I disagree[ Go to top ]

    <david>
    E.g. NumberFormatException. You know that data input from a user may be invalid and needs validating and cleansing before being allowed into the system. This is an entirely expected exceptional flow.
    </david>

    "Expected exceptional flow" is an oxymoron when it comes to logic implementation. You expect *invalid data* and the correct terms here are preconditions, postconditions and invariants. RUP sucks bigtime anyway...

    You should read up on what Betrand Meyer has to say about the matter. Not only does his approach have a strong theory behind it (in Eiffel, Sather, et. al.), it work like a sharm in practice too.

    <david>
    <han>
    The best advice I've seen regarding exception handling strategies is this: If you take out all the exception handling code in your application on a sunny day, will your application still run? If the answer is no you have a problem.
    </han>

    Oh dear.
    </david>

    Oh dear what? If it doesn't work, your logic is dependant on exception clauses. That is just plain crazy.
  33. Re: I disagree[ Go to top ]

    Han,

    I understand your view of coding - exceptions should only exist as runtime exceptions, anything else should be dealt with as a return code. Right?

    The thing is that the world has moved on from there. In C++ the methodology was:

    A Happens regularly? Return error code.
    B Can happen? Use exception.
    C Can't happen? Assert.

    This adapts to Java as
    A Happens regularly? Return error code
    B Can happen? Checked exception
    C Can't happen? Runtime exception

    You want never to use option B in your code. OK, but you're not using the language nearly as well as you might.

    > RUP sucks bigtime anyway...

    The thing is to draw in useful elements from every methodology... not all of it sucks ;-)

    /david
  34. As a practitioner of re-throwing almost all checked exceptions as runtime exceptions, I would like to hear about specific examples from folks who are advocates of checked exceptions where they found them useful. I have probably tried every methodology named here before settling on prefer-unchecked-exceptions, and I find it far and away the best. I've tried wrapping exceptions. I've tried throwing java.lang.Exception as an aggregate of sub-Exceptions, and I've tried just bubbling up all the specific exceptions. All of these I rejected for different reasons, most of which folks have listed above, and even more fundamentally because I found that, with a few exceptions(:, I was rarely doing anything with these Checked exceptions. And every level I got away from the source of the exception, the likelihood I would do anything with it decreased by an order of magnitude. For example, working on a servlet that is handling an exception from 5 levels down was something I NEVER found meaningful, except to know that on the UI level I was going to send the user to an error page.

    Of course, there are uses for checked exceptions. I'd like to avoid being one of the folks making absurd absolute statements(such as the ones that litter the article that started this thread). However, I think they are few and far between. I guess if there are folks out there who find themselves writing software where getting a SQLException or a ConnectException 3 levels removed from where it happened and doing something with it besides failing gracefully, then I would say have at it. But recovering from a database being down, or a server not being found is not something I have ever had to do, and if I was working in an environment where this was something I did have to worry about and plan around, I wouldn't handle it as an exception but as a return value(which, to pile on to a point that others have made, is why I HATE things like NumberFormatException and myriad other similar cases that should be handled as return codes IMO). I guess there's a sweet spot here for certain applications where you have a requirement to handle these things very gracefully(maybe real-time stuff, libraries such as Dmitri mentions, though I would qualify this by saying libraries that are planned on being distributed to an unknown and wide audience...we write lots of libraries at my company but they are for internal consumption and we can agree on what we need to and don't need to handle) but for the majority of cases, unchecked exceptions are the way to go.
  35. The common example that everyone is giving is the DB unavailable exception. Wouldn't you "handle" this by sending a tivoli error to the console to alert the operator that there is a problem, or would you "handle" the exception by emailing someone.

    So is the real question 'Where do you handle this exception', not 'if you should handle this exception' ? The idea of letting this propogate up to the top somewhere is less attractive for me but if the alerting is done by the top most method, I guess this would work.
  36. Re: I disagree[ Go to top ]

    <david>
    Han, I understand your view of coding - exceptions should only exist as runtime exceptions, anything else should be dealt with as a return code. Right?
    </david>

    Wrong. I've only been advocating that checked exceptions are ludicrous.

    <david>
    The thing is that the world has moved on from there.
    </david>

    If checked exceptions has "moved it on", I'd say it's moving in the wrong direction.

    <david>
    In C++ the methodology was:

    A Happens regularly? Return error code.
    B Can happen? Use exception.
    C Can't happen? Assert.

    This adapts to Java as
    A Happens regularly? Return error code
    B Can happen? Checked exception
    C Can't happen? Runtime exception
    </david>

    These exception idioms are overused. If a "thing" can only happend in the event of a failure not attributed to the business logic of your application, exceptions are great (but not checked ones.) But only then.

    A few examples of good (unchecked) exceptions are DivisionByZeroException, OverflowException, IndexOutOfBoundsException, etc... things that are all orthogonal to your app' logic. Exceptions indicating state (couldn't open this and couldn't close that) are counter-productive and leads to bad non-OO error handling, a debugging hell and often break encaptulation. There are ways around the last point, but that again leads to horrific code bloat.

    Your point (C) for Java will from version 1.4 change into "use assertions".

    <david>
    You want never to use option B in your code. OK, but you're not using the language nearly as well as you might.
    </david>

    Disagree. Using checked exceptions is, well, necessary in Java because the API's enforce you to use them. But the most successfull libraries I've seen don't use them at all. For good reasons.

    <david>
    > RUP sucks bigtime anyway...

    The thing is to draw in useful elements from every methodology... not all of it sucks ;-)
    </david>

    That's true, but overall, RUP sucks bigtime as most current methodologies. The "good" ones (like the framework-centric Catalysis) are so complex that only the most skilled organizations can hope to cope with it.

    Those who try usually fail miserably because the designers and architects cannot possibly hope to communicate what the methododology wants them to communicate. The other end is mute (the programmers, that is) in architectural meetings based on RUP-like methodologies.

    Result? Crisis before soon.

    Of course, there are a few success stories but they are rare. Probably because there is a limited number of prodigies around...
  37. Re: I disagree[ Go to top ]

    I would just like to add that Eric Gunnerson of the C# team explained in detail why they dropped checked exceptions:

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

    They appear to have spent conciderable time evaluating checked exceptions and its problems in large projects.

    A crucial point to understand in this discussion is that the problems with checked exceptions appear mainly in large applications. But then agina, this is also the very applications that need a good exception/error recovery strategy.
  38. Re: I disagree[ Go to top ]

    <han>
     I would just like to add that Eric Gunnerson of the C# team explained in detail why they dropped checked exceptions:
    http://discuss.develop.com/archives/wa.exe?A2=ind0011A&L=DOTNET&P=R32820
    </han>


    Yep, read it a while (couple of years?) ago. I remember at the time being incredibly frustrated about why someone as smart as Mr. Gunnerson could completely miss the point of checked exceptions and have no concept of their best use practices.

    And re-reading it, exactly the same feelings came back :-(

    He talks about layers A, B, C, D and a contract between A and D. Clearly it is best practice in that case to use an unchecked exception - as described with security exception earlier.

    That is also a very rare situation - that A should be able to do handling (or indeed should have any knowledge) of failures occurring in D is frankly ridiculous: A will almost certainly be business logic code and D a low level library (doing say - IO?). That you should expect to handle IOExceptions in business logic is a great anti-pattern - how not to write good error handling code...

    Still, I guess C#'s loss is our gain ;-)

    /david
  39. Re: I disagree[ Go to top ]

    <han>
     <david>
    Han, I understand your view of coding - exceptions should only exist as runtime exceptions, anything else should be dealt with as a return code. Right?
    </david>
    Wrong. I've only been advocating that checked exceptions are ludicrous.
    </han>


    Given that I'm saying you only want to use options A and C, and you say the B is ludicrous, I think we are in agreement.

    <han>
    Your point (C) for Java will from version 1.4 change into "use assertions".
    </han>


    Knew you were going to suggest that. Since assertions are debug only, no. Option C stays, assertions are used for pre-condition and post-condition checks (in my code anyway).

    <han>
    Disagree. Using checked exceptions is, well, necessary in Java because the API's enforce you to use them. But the most successfull libraries I've seen don't use them at all. For good reasons.
    </han>


    Clearly. But if you do characterise unchecked exceptions as 'failures' and checked exceptions as 'exceptions', then you're not really using exceptions at all!

    /david
  40. Re: I disagree[ Go to top ]

    <david>
    Knew you were going to suggest that. Since assertions are debug only, no. Option C stays, assertions are used for pre-condition and post-condition checks (in my code anyway).
    </david>

    Which will change when a technology like, say jContract, hopefully find its way into the Java spec.

    Eiffel users rarely use exceptions since they can specify the contract of a given interface in terms of post, pre and invariant conditions. Why, of why, didn't Gosling think of that (well, actually he did but admitted that he and his team didn't know how to implement it correctly at the time... fair enough.)

    <david>
    Clearly. But if you do characterise unchecked exceptions as 'failures' and checked exceptions as 'exceptions', then you're not really using exceptions at all!
    </david>

    Sorry if it came out that way. Exceptions are, just that, exceptions. Not part of the domain logic.
  41. Re: I disagree[ Go to top ]

    <gregor>

    >  <quote>
    >  The interface should throw something like LogPersistenceException.
    >  </quote>
    > I disagree. How would the calling code be able to handle such exception?
    > It can cope with an IOException and ask the user to insert an empty disk or,
    > it can handle a DBException and retry the transaction, but how would this be possible with LogPersistenceException?
    > </gregor>
    >
    > Why should the top level code have to know whether the logger was trying to
    > use the disk or a DB - you are commiting the cardinal error of exposing
    > implementation specifics in your interface...

    That is what I mean, the caller shold not *have to* know about the implementation details. That is why the (most) exceptions should be unchecked.

    But it *could* handle some situation, like full or write protected disk.

    >
    > ... if you added a JMS logger implementation you would have to add a new
    > exception to your interface! Exceptions should always try to match the
    > functional intent of the method call - why should calling code need to know
    > about DBs or disks or messaging or whatever - all it cares about is that it
    > has called the log method to do some logging!!!

    Yes, of course. The caller should not know the internals of the logging method. But why should the logging method catch the underlying exeption only to translate it to LogPersistenceException? Why shouldn't the underlying IOException or DBException pass throgh the logging code (which cannot handle it) to the caller? The only reason I can see, is to translate a checked exception to an unchecked one which carries the checked one.

    >
    > (Actually logging is a bad example -
    >

    Agreed :-)

    >
    > Hypothetically, though, if you were throwing a checked exception out of the
    > log method, you would use a functionally informative LogFailedException, wrap
    > the root Exception (IO or whatever), and insert some useful text to the
    > exception description field ("Check disk..." for the IO failure, etc).

    This would be my strategy, but the LogFailedException would be unchecked.

    >
    > However, in this case, I would make the exception unchecked (but still wrap
    > the same information) - because you really (in the example of the desktop app
    > say) want the exception to propagate straight up to the top level exception
    > handler, where the information can be displayed to the user.

    Exactly! And if IOException or DBException were already unchecked, then there would be no reason to create new exception class. (Well, perhaps, if the logging itself would throw its own exceptions)
     
    > The important question to ask is:
    >
    > "Can this error possibly occur in a correctly configured and running
    > system, with no coding errors?"

    >
    > If it can then it is a checked exception (at least as far as the next code
    > layer - ask the same question again there), if not it is unchecked.

    I don't really agree with this as a sole criterion. For me, an exception should be checked only if the caller has to be forced to handle it (or to force its caller to handle it)

    Unfortunately I cannot give an example of a situation where checked exception would be necessary.
  42. Re: I disagree[ Go to top ]

    <gregor>
    > If it can then it is a checked exception (at least as far as the next code
    > layer - ask the same question again there), if not it is unchecked.

    I don't really agree with this as a sole criterion. For me, an exception should be checked only if the caller has to be forced to handle it (or to force its caller to handle it)
    </gregor>


    Yes, that is the advantage of checked exceptions - nothing is left to doubt. The assumptions are clear: if you use a checked exception it will be handled by the caller, just as if you use an unchecked one, the assumption is that it will only be handled by the top level handler.

    But also not quite: An exception should be checked if the caller should be given the option of what to do about it (even if it just decides to wrap the checked exception in an unchecked one and re-throw - the "I can't do anything with this" option).

    Remember - libraries (especially low-level ones) may be called in many different situations by quite different code - it is arrogant in many cases to handle possible errors by throwing an unchecked exception (the assumption of which must be that it goes straight up to the top level handler).

    For instance SQLException: Most of the time you'll just wrap that in a runtime exception and re-throw ("DB is screwed - all bets are off"), but there are situations where you want to try something and see if it fails, or on a connection.close() where it makes no sense to fail the whole request to the user if you've got good data to send back.

    From a library writers point of view, SQLException as a checked exception is the correct one: the error may well be part of a normal exceptional flow... it is down to the caller to make the decision whether it is or isn't.

    /david
  43. <david>
    The assumptions are clear: if you use a checked exception it will be handled by the caller, just as if you use an unchecked one, the assumption is that it will only be handled by the top level handler.

    But also not quite: An exception should be checked if the caller should be given the option of what to do about it (even if it just decides to wrap the checked exception in an unchecked one and re-throw - the "I can't do anything with this" option).
    </david>

    An unchecked exception also gives the caller the choice of handling it. It just doesn't enforce this "choice" (in which case it's not really a choice). When I code a method to throw an unchecked exception I don't assume that the exception will only be handled by the top level handler, only that it will most likely be left to propagate as in most cases it can't be recovered by the caller--hence the caller shouldn't be forced to catch or rethrow. Thus, for example, a DAO implementation using JDO can choose to catch JDO exceptions that may be recoverable under some circumstances.

    Rod
  44. <rod>
    An unchecked exception also gives the caller the choice of handling it.
    </rod>


    Yes, but there is no contract (or, at least a very poor one) - if I chose to change the exception that is thrown, nothing will be flagged in the compiler to show that the calling code no longer handles it.

    <rod>
    It just doesn't enforce this "choice" (in which case it's not really a choice).
    </rod>


    There is choice as to what to do with it - you're just not allowed to bury your head in the sand and pretend it doesn't exist!

    <rod>
    When I code a method to throw an unchecked exception I don't assume that the exception will only be handled by the top level handler, only that it will most likely be left to propagate as in most cases it can't be recovered by the caller--hence the caller shouldn't be forced to catch or rethrow.
    </rod>


    But there is a decision to be made here - either the system is in a known state and can continue, or it is not and you can't. That decision has to be made, and would help the calling code if you indicate to it that this decision does have to be made.

    You have (whether you like it of not) made that decision on behalf of the calling code - the assumption with an unchecked exception is that the system is in an unstable state and that the exception will flow up to the top level handler.

    That is what will happen if no further action is taken, and so that is what you should assume will happen.

    /david
  45. <quote>
    An unchecked exception also gives the caller the choice of handling it. It just doesn't enforce this "choice" (in which case it's not really a choice). When I code a method to throw an unchecked exception I don't assume that the exception will only be handled by the top level handler, only that it will most likely be left to propagate as in most cases it can't be recovered by the caller--hence the caller shouldn't be forced to catch or rethrow. Thus, for example, a DAO implementation using JDO can choose to catch JDO exceptions that may be recoverable under some circumstances.
    </quote>

    And let's not forget that it is possible to specify unchecked exceptions in throws clauses and in JavaDoc! So you can indeed inform the potential caller which exceptions might get thrown, especially ones that he might be capable of handling. If the caller decides to ignore that, then he does nothing special.

    I consider this kind of the best of both worlds for unexpected runtime exceptions - the approach that would be most appropriate for JDBC, IMHO. Connection.close should mention that it may throw a runtime exception, so that calling code may catch and swallow it if it likes to proceed nevertheless - but the method shouldn't not force the caller to catch it.

    Regarding "exceptional workflows": That's where checked exceptions really make sense: not representing system errors, but exceptions in reaction to user input (like NumberFormatException etc).

    Finally, regarding the File example: You don't have to rely on FileNotFoundException to detect that a file doesn't exist! Just create a new File instance and call its "exists()" method before trying to open it...

    Juergen
  46. <juergen>
    Connection.close should mention that it may throw a runtime exception, so that calling code may catch and swallow it if it likes to proceed nevertheless - but the method shouldn't not force the caller to catch it.
    </juergen>


    Great - so by default (if I'm calling this in an EJB environment), you've specified that my transaction will be rolled back and my EJB destroyed - all without my having any clearly defined say in the matter.

    To be blunt - if I was using you library and I found out that was happening, the air would be blue, and I would be looking at ways to remove your library from my system as soon as reasonably possible.


    The bottom line to exception handling is whether you can get back to a 'known state' or not. You have defaulted the answer to 'No' on my behalf. Thanks!

    Check out http://www.objectarchitects.de/arcus/cookbook/exhandling/ for the Arcus article on a pattern language for error handling for a discussion on 'good' and 'bad' state, and much more.

    /david
  47. <david>
    Great - so by default (if I'm calling this in an EJB environment), you've specified that my transaction will be rolled back and my EJB destroyed - all without my having any clearly defined say in the matter.
    </david>
    No, Juergen hasn't "specified" anything. You could choose to catch the exception and handle it yourself. It's a matter of choice. However, as the database would have disappeared, it's a severe problem, so invoking the default behaviour of the EJB container is reasonable. Assuming that the database is gone, how would you expect the EJB container to commit the transaction, assuming you're using CMT? It would need to communicate with the database to do that. Your approach would most likely amount to pretending that you'd gotten back to a known state when in fact your application was in big trouble.

    This is a case where the likelihood of being able to recover is slim. Hence it makes more sense to model the exception as unchecked.

    <david>
    To be blunt - if I was using you library and I found out that was happening, the air would be blue, and I would be looking at ways to remove your library from my system as soon as reasonably possible.
    </david>
    Whether or not you experience extreme rage when you encounter other people's programming practices is not relevant. You're free to choose libraries you feel comfortable with: this situation shouldn't arise because you should understand a framework's design and read its Javadoc before you choose to use it.

    Regards,
    Rod
  48. <rod>
    No, Juergen hasn't "specified" anything.
    </rod>


    He most definitely has - he has defined for me what the default handling for that error is. And he has defined an extremely destructive default, too.

    He has also made it that I have to go to the JavaDocs (if he's remembered to doc it - easy to forget with runtime exceptions) or source to find out that this will happen. Busy programmers might mean to do it, but won't always.

    He is setting me up for a fall...

    <rod>
    However, as the database would have disappeared, it's a severe problem
    </rod>


    You're making assumptions on my behalf again - could just be that the connection was forceably recycled before I got around to closing it. Could be temporary, could be permanent...

    <rod>
    This is a case where the likelihood of being able to recover is slim. Hence it makes more sense to model the exception as unchecked.
    </rod>


    Why are you in such a hurry to make that decision for me? Why not give me the checked exception? Then I know I have to make the decision and can do so. I know the context of my DB call and so am much better placed to make that decision than you are in the library.

    <rod>
    Whether or not you experience extreme rage when you encounter other people's programming practices is not relevant.
    </rod>


    ;-) Since it is triggered by someone making unwarranted assumptions about things that should have been left to me, I might argue that it is reasonable!

    <rod>
    You're free to choose libraries you feel comfortable with: this situation shouldn't arise because you should understand a framework's design and read its Javadoc before you choose to use it.
    </rod>


    Re-reading part of the arcus paper, it talks about 'failure' and 'exception' modes. I interpret that so checked exceptions represent the 'exception' mode and runtime ones the 'failure' mode.

    Why would I be keen to use a framework that is so keen to commit the system straight into 'failure' mode without any real 'exception' mode handling. I would have to regard that as a major risk of using the framework, and would strive to avoid it.

    The other risks of using a framework that behaves as you describe are:

    Maintenance: The documentation would have to be completely re-read before doing any upgrade, however small, vastly increasing the upgrade task.

    Paranonia: Programmers using the framework will start defensively coding against random unchecked exceptions by trapping RuntimeException (or worse!). This can easily break correct uses of Unchecked Exceptions, where they are used to communicate errors through layers that know nothing of the contract (security exceptions being a good example).

    /david
  49. <david>
    You're making assumptions on my behalf again - could just be that the connection was forceably recycled before I got around to closing it. Could be temporary, could be permanent...
    </david>
    You'll need to come up with a better example. This implies that (a) your app server is extremely unwell, with a screwed connection pool (probably not recoverable as this means that transaction management will be screwed as well); or (b) you leave connections open for a long time after you've finished using them (poor practice).

    <david>
    Why would I be keen to use a framework...
    </david>
    No one's forcing you to. This is an area where we're all entitled to our own opinions. Mine and Juergen's choice of programming style and our choice of frameworks differs from yours. It's just that you're insisting that our way is totally invalid.

    Regards,
    Rod
  50. <rod>
    You'll need to come up with a better example.
    </rod>


    Hate to point this out, but the burden of proof is with you: If there is any doubt, even the merest glimmer, that I might need to handle the error, then you should make the contract that I should have the choice...

    You have to be certain that the system is in failure mode to throw a runtime exception. Any doubt, pass it over to me.

    <rod>
    This is an area where we're all entitled to our own opinions.
    </rod>


    Even if the result is that we have to accept flaky software if the two approaches are mixed?

    I would also like to see how you intend to mitigate the risks that I raised in the previous post...

    /david
  51. <rod>

    > You'll need to come up with a better example.
    > </rod>

    > Hate to point this out, but the burden of proof is with you: If there is any doubt, even the merest glimmer, that I might need to handle the error, then you should make the contract that I should have the choice...

    You do have a choice. You can catch the unchecked exception, if you can think of a valid scenario in which you'd want to. So far you haven't come up with a single valid reason to justify every piece of code calling the method being forced to catch a checked exception. My approach gives you the choice of doing something unusual; your approach is to enforce explicit exception handling just in case you ever think of a valid reason to use it.

    > <rod>
    > This is an area where we're all entitled to our own opinions.
    > </rod>

    > Even if the result is that we have to accept flaky software if the two approaches are mixed?

    People don't all think the same way. To ensure the purity of your approach you shouldn't use Java collections, JDO or TopLink, for example. On the other hand, you could accept that people don't all share your views and understand the reasoning behind libraries you use. When I use libraries using checked exceptions exclusively I respect that.

    The logical extension of your position is that it's impossible to write other than flaky software in languages without checked exceptions: that is, every mainstream language other than Java.
  52. <rod>
    To ensure the purity of your approach you shouldn't use Java collections
    </rod>


    You raise an interesting question about libraries. The ConcurrentModificationException on the iterators of the Collecitons API is a particularly good example to think about:

    There are two theoretical ways to use a collection iterator in a multi-threaded environment:

    1) Ensure that the access to the collection is synchronised. This would mean that the only circumstance that the exception could be thrown would be as a result of a coding error. Thus the exception can be unchecked.

    2) Allow the code to be run in unsynchronised environments: Try it, if it fails, catch the exception and retry. In that usage pattern, the exception should be checked, to ensure that the quite real chance of an error is handled.

    By making the ConcurrentModificationException unchecked, the library authors are clearly limiting the usage pattern of the library to that of (1) only.

    (Interestingly, re-checking the JavaDoc on that exception, it states the following:

    Therefore, it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

    Thus the documented expected usage matches the type of exception thrown).

    But the conclusion is clear (in my mind, anyway!):

    Choosing to throw unchecked exceptions from libraries may limit the usage patterns available to the user of the library (and these restrictions should be documented if at all possible). Conversely, checked exceptions allow full flexibility at the cost of some convenience to the user.

    The library developer has to make a decision as to what the usage patterns might be, and whether to favour convenience over flexibility. The Java API developers (unsurprisingly, to my mind) tend to prefer the latter, being unsure quite how the API might be used (or unwilling to constrain usage). I don't think it is really fair to criticise them too harshly for that.

    /david
  53. David,

    You seem to have a problem with people making design decisions "on your behalf". But isn't any library the outcome of design decision ? Actually, frameworks are just that: they are "in a hurry" to make decisions for you in order for history not to repeat itself in case of bad experiences.

    You are keen on checked exceptions and you have your own reasons, that's fine. You probably have had no bad experience with it. Other people are not and they are not very happy that Sun made the decision "on their behalf" to use checked exceptions making JDBC programming a pain in the neck and so much error-prone (countless stories of statements and connections not properly closed, cursor and connection shortages and memory leaks as a consequence of the massive use of checked exceptions). This whole "decision-on-my-behalf" point is utterly ludicrous anyway because you can choose to catch these exceptions.

    Now, may I suggest you take a deeper look at the Spring framework ? Spring JDBC is not just about exception handling, it's about properly managing the way statements and connections are closed in order to focus on the SQL without taking exaggerated care about JDBC syntax. All I can say is that JDBC developers around me are very happy with Spring and the way exceptions are being handled. I for one am pretty happy to hide 80% of the JDBC-specific-not-related-to-business code.

    "Paranonia: Programmers using the framework will start defensively coding against random unchecked exceptions by trapping RuntimeException (or worse!)."

    Ok then. Let me turn it around: with remote EJBs, do you use RemoteException or do you check any of its 19 random sub-classes ? With transactions, do you catch Exception or the 5 specific random exceptions one by one ? How can you sleep with the runtime EJBException ? :) Spring offers a generic DataAccessException that holds exactly the same position as all these exceptions: choose to catch the generic one or catch them one by one.

    "Maintenance: The documentation would have to be completely re-read before doing any upgrade, however small, vastly increasing the upgrade task."

    Well in the case of Spring JDBC, all unchecked exceptions extend DataAccessException so there is little chance that your upgrade task that much increased (probably as hard as EJBException).

    Best thing, before you get too critical against Spring, just use it. And relax, it's spring... :))

                    Yann
  54. Re: Spring JDBC[ Go to top ]

    Yann,

    Have you got a URL for that (Google yields nothing...)?

    /david
  55. Re: Spring JDBC[ Go to top ]

    David,

    Sure. Here it is: http://sourceforge.net/projects/springframework.

                    Yann
  56. <david>
    I know the context of my DB call and so am much better placed to make that decision than you are in the library.
    </david>

    I think this is the best summary of the whole debate, and it perfectly illustrates what I was trying to say above about making sure that the code that handles the exception is the most appropriate one. And checked exceptions make that possible.

    Thanks, David.

    <rod>
    You're free to choose libraries you feel comfortable with: this situation shouldn't arise because you should understand a framework's design and read its Javadoc before you choose to use it.
    </rod>

    I don't think it's realistic in the world we live in to assume that the JavaDoc will always match exactly the code you are using. Eventually, you always end up having to read the code, if only to make sure the code really does what the documentation says.

    --
    Cedric
    http://beust.com/weblog
  57. Cédric,

    "I think this is the best summary of the whole debate, and it perfectly illustrates what I was trying to say above about making sure that the code that handles the exception is the most appropriate one. And checked exceptions make that possible."

    So do runtime exceptions.

    Actually, it seems that the whole point is about whether or not to sacrifice checked exceptions (and a Javadoc guaranteed to be in line with code) to readability and ease of programming, because technically, it is possible to do everything using both ways. All exceptions can be caught whenever appropriate.

    David seems unhappy that some of his SQLExceptions be catched upfront. That's fair enough. And that's a different problem. He still can catch the wrapping runtime exception and do his specific handling, and benefit from the simplicity brought about by Spring. Or he can choose to fork the project and remove those naughty runtime exceptions. :) In any case, as I said, a framework is the sum of design decisions. Most of the time, in my experience, SQLExceptions are caught to log messages, properly close statements and connections, and rollback transactions when transaction is not declarative. It is quite unusual to try to recover the connection and retry the transaction at this level. It's my empirical experience that in case of a failure, the current transaction is rolled back overall, or abandoned if the connection is dead and the whole transaction is restarted from a higher business level. The same applies in case of RemoteException. But again, it is a design decision and whether the exception is checked or unchecked is totally irrelevant.

    As always, there is a subjective trade-off to do, hence the endless debates. In the end, it should be up to the person in charge of technical specifications to decide about the global exception strategy. The important thing is to stick to one policy throughout a project.

                    Yann
  58. I digress[ Go to top ]

    Unfortunately I cannot give an example of a situation where checked exception would be necessary.

    Necessary? No, of course they aren't necessary. If you build the gates of heaven so strictly, then we're all just going to revert to our sinful ways. ;-)

    Look at it in a different light. Which checked exceptions have you found to be annoying, and why?

    1. IOException - for some reason, the streams (etc.) APIs have never annoyed me with the IOException stuff.

    2. SQLException - for some reason, this one has annoyed me, particularly on no-op methods that couldn't throw an exception if they wanted to ....

    3. Iterator.next() and Enumeration.getNext() ... both throw a runtime exception, and if it weren't, I'd have been very upset.

    4. wait() throws InterruptedException ... and generally that has been an annoying one ... maybe it's right though.

    5. Class.forName() and newInstance() have a mottled assortment of Error, RuntimeException and checked Exception sub-classes thrown. That's a big bottle of annoying, but at least the exceptions can be explained on an individual basis.

    6. RMI - RemoteException - I always found this to be pointless (sorry Ced!), and based on a Sun document written by people who write documents and not applications (sorry Sun!).

    7. NumberFormatException - always seemed reasonable to me. Actually kind of handy when parsing inputs that could have defaults:

    public static void main(String[] asArg)
    {
    // default number of iterations and test buffer size
    int cIters = 10;
    int cbBuf = 500;

    // parse command line overrides (if they're available)
    try
        {
        cIters = Integer.parseInt(asArg[0]);
        cbBuf = Integer.parseInt(asArg[1]);
        }
    catch (NumberFormatException e) {}

    // ...
    }

    Peace,

    Cameron Purdy
    Tangosol, Inc.
    Coherence: Easily share live data across a cluster!
  59. I digress[ Go to top ]

    <cameron>
    6. RMI - RemoteException - I always found this to be pointless (sorry Ced!), and based on a Sun document written by people who write documents and not applications (sorry Sun!).
    </cameron>


    I know what you mean: This debate has raged since RMI was created.

    My feeling is that, although it is a pain, it stops people from assuming that a remote method call is just like a local one. There is a huge difference though: The mechanism of local call can never fail (unless your VM is terminally shagged), whereas the mechanism of a remote call, possibly going half-way round the world, can (and will, on occasion) fail.

    To digress the digression - I remember reading in the RMI docs for one revision (1.2? 1.3?) that RuntimeExceptions could be transparently communicated back to the client. That scared the living daylights out of me... that random unchecked exceptions might appear in a client that knows nothing about the context of the error.

    Anyone know anything more about that? What were the details, and why did they make that change? Anyone?

    /david
  60. Not so[ Go to top ]

    <konstantin>
    Good example of bad design :).
    </konstantin>

    Exactly!

    <konstantin>
    The interface should throw something like LogPersistenceException
    </konstantin>

    Indeed. But this is a different concern than using/not using checked exceptions.

    The point is - no matter what exception you throw in the face of caller, it signifies something about the internal state of the class. If it said something about the public state of the class, well then that state would be part of the signatures; which is, of course, not the case.

    Making the exception checked means that it's part of the method signature and hence the public interface (whether it's a Java interface or not...)

    So the discussion should really be whether or not exception declarations should be part of the signature. In my head, it should definitely not be so.

    I think (well, hope) that 5-10 years from now, exceptions are dead and all error handling is concidered a cross-cutting concern that can only be handled by aspect orientation.
  61. Not so[ Go to top ]

    So the discussion should really be whether or not exception declarations should >be part of the signature. In my head, it should definitely not be so.


    IMO: Exceptions are very valuable parts of method signature. The mind shift I mentioned before is exactly about considering Exception clause as part of signature that provides valuable information.
  62. Not so[ Go to top ]

    <han>
    Without going into detail, we (and others - check google) have found that the *only* sensisble place to use checked exceptions is the very place you KNOW that the caller can take appropriate actions to rectify the abnormal program state
    </han>

    If you are making assumptions on who is going to call you, then the scope of your code will be extremely limited. Basically, it will be a self-contained application not destined to much reuse.

    You don't have that luxury when you write a library or code for a server because you simply can't (and shouldn't) anticipate who will be calling you.

    A lot of people misunderstand checked exceptions because they are under the impression that checked exceptions split the world in two: those who throw exceptions and those who can catch them.

    The reality is more complex. It's a spectrum of possibilities. You don't know where the responsibilities are, you don't know who's calling you and sometimes, you're not even sure who you are calling yourself (magic of polymorphism).

    The only thing you know for sure is the conditions that will make your code fail. The only reasonable thing to in that case is to throw an exception, and this exception will sometimes be checked and sometimes not. Let the caller figure out if they can handle it or if they should just pass it on.

    Conversely, if your code is making use of methods that throw checked exceptions that you don't know how to deal with, just declare them in your throws them and get back to what you were doing.

    --
    Cedric
    http://beust.com/weblog
  63. Not so[ Go to top ]

    I'd put what Han said differently. Checked exceptions make sense in places where you want to _force_ your clients (whoever they are) to take some action.
    The action might be ignoring it, passing it on etc.. But you want to _force_ the client to be aware of something going wrong. With runtime, the client can be blisfully ignorant of anyting that can go wrong with your code (because presumably something up there will handle it).
    My favourite example here is Connection.close() throwing checked SQLException. 99+% of the code around cannot and will not do anything except log an error message and abort (as likely someone pulled the plug on the DB). Which can and should be done somewhere at the top of the call stack - about the place where the transaction started. If an unplugged DB (or an invalid argument in a SQL call - i.e. a bug) isn't a runtime exception, I don't know what is.
    Regards,
    Vlad
  64. <quote>
    My favourite example here is Connection.close() throwing checked SQLException. 99+% of the code around cannot and will not do anything except log an error message and abort (as likely someone pulled the plug on the DB). Which can and should be done somewhere at the top of the call stack - about the place where the transaction started. If an unplugged DB (or an invalid argument in a SQL call - i.e. a bug) isn't a runtime exception, I don't know what is.
    </quote>

    I wholeheartedly agree, JDBC is a primary example of checked exception overuse. Consider executing a simple query, starting with a DataSource instance. As nearly every method in Connection/Statement/ResultSet throws SQLException, you're forced to go into try-and-catch hell, even in catch blocks for previous exceptions. Most of them are conceptually runtime exceptions, as they represent system misconfiguration or application bugs. Connection.close, Statement.close, ResultSet.close, even Connection.getAutocommit... there's nothing recoverable here.

    But for proper JDBC exception handling, you have to catch them in subtle ways to close resources correctly. Have a look at the example at the bottom of Tomcat's JNDI Datasource HOW-TO. 3 exception-swallowing close calls... those close methods simply shouldn't throw checked exceptions. Unfortunately, simpler catching strategies risk unclosed resources or losing the original exception, at least with certain JDBC drivers, so you have to do it this way with plain JDBC to be on the safe side.

    As Rod and Geoff have already mentioned, JDO uses runtime exceptions - I consider that a good thing. It's one of the few things that I'm not fond of in Hibernate - it throws a checked HibernateException on nearly every call, basically forcing application programmers into similar programming patterns as JDBC.

    Of course, you can always work around this yourself with some helper classes, but this isn't a really trivial thing using the library approach. A comfortable way is a template approach - "inversion of control", providing e.g. callbacks for result set extraction. Rod has elaborated on this approach in his book. BTW, the framework that comes with the book resp. its actively developed current version (now called Spring Framework) provides sophisticated support in this respect, among many other things - in a very non-intrusive, reusable way.

    Juergen
    (Spring Framework developer)

    P.S.: The Spring Framework hasn't a formal release yet but will have soon. Watch out! ;-) And we provide convenient templating approaches for transaction handling and Hibernate data access too...
  65. Connection.close()[ Go to top ]

    My favourite example here is Connection.close() throwing checked

    > SQLException. 99+% of the code around cannot and will not do anything except > log an error message and abort (as likely someone pulled the plug on the
    > DB). Which can and should be done somewhere at the top of the call stack -
    > about the place where the transaction started. If an unplugged DB (or an
    > invalid argument in a SQL call - i.e. a bug) isn't a runtime exception, I
    > don't know what is.
    >

    This is an interesting example. Although you are absolutely right, that in a lot of cases this is an annoyance, there is also very valid JDBC coding that actually commits a transaction by closing a connection (no EJB, no transaction monitor , just plain client side sql programming required). In fact, one could argue that it is the most efficient way to commit a transaction. Since commits can go wrong for other reasons than bugs, I think it is a perfectly good idea to have this exception as part of interface. In my opionion, this qualifies for something more than a RuntimeException.

    However I also agree that the language should provide somethings like declared and undeclared exceptions and map declared to undeclared at compile time with a warning rather then forcing handling of checked exceptions.
  66. Connection.close()[ Go to top ]

    Well, I could argue that using a connection for each transaction is bad because even using the same DB (and for example Sybase has different autocommit on close strategy then Oracle), you can usually set the behaviour. So your app relies on DB settings, which may not be known to your DBAs, openin a connection for each transaction is costly etc.. But anyway, back to exceptions.
    My point is, that if close() was throwing runtime exception, it would not mean you cannot use it to commit your transactions. But it would not force the majority of users who are not using it like this to swallow the exception - instead of dealing with it on some higher level where they catch runtime exceptions (as I think they should). Even if you are using it for commit, what exactly can your application do here that is different from say getting a NPE from this call (due to an uncommon bug in JDBC driver)?
    Regards,
    Vlad
  67. Good point[ Go to top ]

    [quote]
    A little known problem with checked exceptions is that it breaks encaptulation as the software at hand evolves. To see why, consider a class that logs error. This class may offer public method such as "logError" and "logWarning", both throwing a FileException when logging fails. Now, in version 2 of this log class the implementation is changed so that it logs to a database instead and now the checked exception becomes DBError. At this point, all clients fail...
    [/quote]

    Moral of the story: don't expose implementation details outside of your class. Your logError and logWarning should throw a LoggingException.

    -Chris
  68. I think IOException is a good example of an exception hierarchy that makes sense. Consider a user interface where a a user enters a filename and hits open.

    try{
       openTheFile(filename);
    }catch(FileNotFoundException fnfe){
       //gives the user a good idea of how to correct the problem
       System.out.println(fnfe.getMessage());
    }catch(IOException ioe){
       //might give the user some idea of how to correct the problem
       //depending on message but it's pretty much impossible to clarify
       System.out.println("an unknown I/O exception occurred while accessing file: " + filename + ". please try again.");
       System.out.println("the system reported the following error: " ioe.getMessage());
      
    }catch(Exception e){
       //no idea what went wrong. Report as internal error
        System.out.println("an unknown internal error occurred.");
        e.printStackTrace();
    }

    In this case the hierarchy is useful because FileNotFoundException has meaning that can be propogated to a user for recovery. If it's not a FileNotFoundException, some other IOException might have a massage the user could make sense of. When you get to a generic exception, you pretty much have no choice but to report an internal exception. The order of the catch block is obviously paramount.
  69. I have to say I agree with Bruce Eckel, I've done exactly the same as him on occasions.
    <eckel>
    ...
    } catch (SomeKindOfException e) {}

    </eckel>

    I think it's important to have caught exceptions, but maybe you shouldn't force the programmer to catch them at the next level. The compiler could warn that a checked exception wasn't trapped and allow the programmer to make his own decision as to whether he wants to trap it there or at a higher level.

    Paul Parsons
    The Server People
  70. Agreed[ Go to top ]

    <paul>
    I think it's important to have caught exceptions, but maybe you shouldn't force the programmer to catch them at the next level. The compiler could warn that a checked exception wasn't trapped and allow the programmer to make his own decision as to whether he wants to trap it there or at a higher level.
    </paul>

    I agree with this statement. If there was an option provided by compiler to warn about all unhandled checked exceptions in every method, it would not have an adverse impact on robustness and for some people would improve productivity. Personally I would still stick to old fashion way of either handle, or rethrow, or wrap-and-rethrow, but what you describe is definitely one of the viable compromises.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  71. One of the most common arguments that I hear in defense of throwing unchecked exceptions is that with checked exceptions code becomes less readable. Well, this opinion obviously proves either lack of real-life expertise, not knowing good programming techniques (some of which are described in the article), or pure laziness as it was pointed out in the article.

    > </dmitriy>
    > This isn't an argument: it's an attack on people who hold a different view to yourself as being inexperienced, ignorant or lazy. Your category of the inexperienced, ignorant and lazy includes Bruce Eckel (the editor has added a link above), myself, the designers of C#,

    <rod>
    Joshua Bloch ("Item 41: Avoid unnecessary use of checked exceptions")
    </rod>

    Well, this is similar to saying "Drinking too much coke is bad for your health". Nobody is going to disagree with that, and it certainly doesn't mean that Josh is against checked exceptions.

    <rod>
    Readability matters. When code is forced to catch fatal exceptions it can't handle that reduces readability for no value
    </rod>

    You are never forced to catch. And I don't think that declaring that exception in your throws clause gets in the way of readability. And even if you disagree, readability is a subjective matter, so it should certainly not be the main reason to dismiss checked exceptions altogether.

    --
    Cedric
    http://beust.com/weblog
  72. <cedric>
    Well, this is similar to saying "Drinking too much coke is bad for your health". Nobody is going to disagree with that, and it certainly doesn't mean that Josh is against checked exceptions.
    </cedric>
    Neither am I "against checked exceptions": I'm just against the view that Dmitriy seemed to be expressing that virtually all exceptions in Java applications should be checked, and was pointing out that Joshua Bloch agrees with me.

    <cedric>
    You are never forced to catch. And I don't think that declaring that exception in your throws clause gets in the way of readability. And even if you disagree, readability is a subjective matter, so it should certainly not be the main reason to dismiss checked exceptions altogether.
    </cedric>
    I guess you mean rethrowing? By rethrowing you're just ducking the problem, and very likely pushing a low-level exception up to higher-level components that won't, and probably shouldn't, understand it. Somewhere up the stack someone will decide that writing 5 catch blocks isn't readable and will catch (Exception ex).

    Readability isn't entirely subjective, anyway, at least where volume of code is concerned.

    Regards,
    Rod
  73. <cedric>
    You are never forced to catch. And I don't think that declaring that exception in your throws clause gets in the way of readability.
    </cedric>

    <rod>
    I guess you mean rethrowing?
    </rod>

    No no, I mean exactly what I said above (;-)): declaring the exception in your throws clause.

    As for "ducking the problem", yes! That's exactly what this is about. You can't handle this exception, let someone "at a higher level" see if they can, and just mind your business knowing that if your code is running, nothing went wrong.

    This is, by the way, another powerful virtue of checked exceptions: if your code is running in the try{} block, you have quite a few certainties on the existence and validity of the resources you need to execute properly.

    --
    Cedric
    http://beust.com/weblog
  74. <rod>
    I guess you mean rethrowing?
    </rod>
    <cedric>
    No no, I mean exactly what I said above (;-)): declaring the exception in your throws clause.
    </cedric>
    This is actually what I meant: I just phrased it extremely badly :-( I should have said "letting it bubble up the stack".

    > As for "ducking the problem", yes! That's exactly what this is about. You can't handle this exception, let someone "at a higher level" see if they can, and just mind your business knowing that if your code is running, nothing went wrong.

    Most often this means letting an exception at too low a level of abstraction propagate. So it's often necessary to catch the exception and wrap it in a higher-level exception. If the exception is truly fatal, several classes may be forced to do this for no real gain.

    Regards,
    Rod
  75. <cedric>
    Well, this is similar to saying "Drinking too much coke is bad for your health". Nobody is going to disagree with that, and it certainly doesn't mean that Josh is against checked exceptions.
    </cedric>
    <rod>
    Neither am I "against checked exceptions": I'm just against the view that Dmitriy seemed to be expressing that virtually all exceptions in Java applications should be checked, and was pointing out that Joshua Bloch agrees with me.
    </rod>

    Rod, I don't know where you got an impression that I push for all exceptions in Java to be checked. I certainly did not say it in any of my replies, so I suppose you made it up.

    The point of view I am trying to defend is exactly the point of view that the author, Daniel F. Savarese, articulates in the article, which is certainly not against unchecked exceptions, but on the contrary, for proper use of them.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  76. <dmitriy>
    Rod, I don't know where you got an impression that I push for all exceptions in Java to be checked. I certainly did not say it in any of my replies, so I suppose you made it up.
    </dmitriy>
    Well if I misunderstood I'm sorry. I certainly didn't "make it up". I got the impression that your position was far more strongly against unchecked exceptions than the article's.

    Rod
  77. <rod>
    Well if I misunderstood I'm sorry. I certainly didn't "make it up". I got the impression that your position was far more strongly against unchecked exceptions than the article's.
    </rod>
    Hm... Again, I don't know whatever gave you that impression, but what really matters is that we clearly understand right now where we both stand on the issue;-)

    To avoid future misunderstandings, I will reitirate again that, just like the author of the article, I beleive that if you are righting your own solution or a library that noone but you or others in your company will use, then you may elect to use unchecked exceptions if you think that it will improve your productivity. Personally, I wouldn't do it, but I am certainly not against it.

    And, by the way, I think that Java Collections API (referring to JDK) is one of the best examples of proper use of unchecked exceptions.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  78. Changes to Java Needed[ Go to top ]

    <paul holser>
    i suppose making all exceptions unchecked wouldn't be a terrible thing. however, if the motive for
    wanting all exceptions unchecked is to avoid documenting the eventualities, avoiding testing the
    exceptional cases, sloth, or short-term programmer convenience (thanks Mark Johnson), count me out.
    </paul holser>
    I broadly agree. The idea of an Checked exception is to let the developer know that a problem could occur and he should deal with it in some way. However, the mechanism provided through try/catch blocks and a throws clause has led to readability problems. What I propose and probably start thinking about are extensions to the java language. How about some Design By Contract Rules where the developer can specify that he has ignored certain exceptions (allow them to propogate upwards), swallowed them, or allow them be handled by Generic Exception Handlers. Writing such DBC rules can be made easier by IDEs. Any other solution is welcome too. However it must satisfy the twin criteria of A) Documenting the approach used to handle the various exceptions and B) Allowing the code to be readable.
  79. This isn't an argument: it's an attack on people who hold a different view to yourself as being inexperienced, ignorant or lazy. Your category of the inexperienced, ignorant and lazy includes Bruce Eckel (the editor has added a link above),...


    Out of curiosity and for what it's worth: Did anyone notice that Bruce Eckel's code from the included link (http://www.mindview.net/Etc/Discussions/CheckedExceptions) does *not* compile? :)

    Paul
  80. http://jinx.swiki.net/352
  81. Some programmers write elaborate exception handling/generating frameworks. They extend existing exceptions and create new types of exceptions to create and throw. I think this is a waste of time.

    1. Don't extend Exception to create unique types of exceptions
    2. Catch the exceptions in a a part of the app where the user can decide what to do.
  82. Let me start by saying that I do not like checked exceptions paradigm. And that the suggestion of making checked exceptions a compiler warning is both simple and brilliant. This enables a declaration of a contract from the provider and the ability to handle the exception or ignore it by the caller.

    Why don't I like checked exceptions? Personally I believe they require orthongional light-weight objects to address an issue that they shouldn't have to. When your working with multiple logical layers in a large system you something needs to be done with this exception otherwise the entire system becomes compromized. In a lot of circumstances where you have time pressures, laziness, or inexperience these exceptions are swallowed:

    try {
     // do something
    } catch (Exception e) {
      e.printStackTrace(System.err);
    }

    At first glance you might think, hey well it's been handled right. But the fact is that in all to many circumstances the above code snippet in a single instance or prolifereated throughout a system will cost an exorbitant amount in debugging time and money. What happens if the code above is deep in a framework? This little ripple from a swallowed exception deep down will manifest over and over again as another problem.

    The point is without forethought and a thorough understanding of all interaction points throughout the application checked exceptions can cause one too many headaches. When working in parallel with others or for other reasons like those state above swallowing will happen. And without properly propagating errors your setting yourself up.

    Personally I would like to handle the exception once rather then daisy-chain several exceptions together. An Unchecked exception paradigm will allow a cordinating and controlling part of an application to handle the exception and the state of the system.

    But for now we have checked exceptions and there is a pretty good article on: http://www.softwarereality.com/programming/exception_handling.jsp. It talks about building an robust exception handling framework.

    Enjoy!
  83. <quote>
    Let me start by saying that I do not like checked exceptions paradigm. And that the suggestion of making checked exceptions a compiler warning is both simple and brilliant. This enables a declaration of a contract from the provider and the ability to handle the exception or ignore it by the caller.
    </quote>

    it might be a training issue/bad habit, but a lot of developers (including myself) will ignore/switch off any compiler warning. I do the same with deprecated methods.
  84. When your working with multiple logical layers in a large system you

    > something needs to be done with this exception otherwise the entire
    > system becomes compromized. In a lot of circumstances where you have time
    > pressures, laziness, or inexperience these exceptions are swallowed:
    >
    > try {
    >  // do something
    > } catch (Exception e) {
    >   e.printStackTrace(System.err);
    > }

    are checked exceptions the problem here, or the aforementioned laziness/inexperience? 8^)

    look, error handling is a concern that pervades the entire application. if a team does not address the responsibilities of such error handling from the beginning of a project, whether checked or unchecked exceptions are the order of the day, you're toast.

    for the record, i prefer checked exceptions. because they're part of a method's contract, just like return type and parameter types, i know what eventualities to be prepared for when calling a method. i can choose to handle the fault right there, or if the immediate caller can't/shouldn't deal with it, wrap it or bubble it up to my caller, depending on where the caller sits in the architecture and whose architectural responsibility it is to at long last report the fault/retry the operation/whatever should happen next. better yet, the compiler tells me when i haven't appropriately acknowledged an eventuality.

    i suppose making all exceptions unchecked wouldn't be a terrible thing. however, if the motive for wanting all exceptions unchecked is to avoid documenting the eventualities, avoiding testing the exceptional cases, sloth, or short-term programmer convenience (thanks Mark Johnson), count me out.
  85. I'd like to fade back to a pattern from our C past;

    HANDLE nHan = getXHandle();
    if ( nHan == NULL ) {
        // Bomb out
    }

    useHandle(nHan);
    releaseHandle(nHan);

    Checked exceptions are meant to handle that case in OO languages, where the contract states that a value/object is unusable.

    It makes no sense to call useHandle if nHan == NULL, and it should make no
    sense to call object methods after a checked exception.

    Now take the other case;

    HANDLE nHan = getPowerHandle();
    if ( handleType(nHan) == POWER_HANDLE ) {
        usePowerHandle(nHan);
    } else if ( handleType(nHan) == WEEDY_HANDLE ) {
        // What to do if no power handle?
        // Hmmm
        useBogStdHandle(nHan);
    }
    releaseHandle(nHan);

    Why do we have exceptions, to allow for clearer code, but the underlying reasons are the same reasons that we checked return codes from procedural languages. Sometimes bad things happen that mean all assumptions about state are off, and sometimes unexpected things happen that may have little impact.
  86. Notice the title of this thread. Perhaps there is reason this debate is eternal. Why don't we save our breath for a debate that CAN be resolved (.Net vs Java, are EJBs good?, is JBoss evil, ...)

    Ryan
  87. <ryan>
    Notice the title of this thread. Perhaps there is reason this debate is eternal. Why don't we save our breath for a debate that CAN be resolved (.Net vs Java, are EJBs good?, is JBoss evil, ...)
    </ryan>

    .NET vs. Java resolved ;-) That was a joke, right?
  88. Examples needed[ Go to top ]

    Following the whole debate, i feel more and more, that we should discuss some concrete examples about exception handling.

    I'm not quite sure whether checked exceptions are generally something good or bad, in many cases i have found them annoying.

    Take some typical exceptions when dealing with entity beans, like javax.ejb.CreateException and its subclass javax.ejb.DuplicateKeyException.

    Usually i'm creating beans with surrogate keys created by some key generator. Getting a DuplicateKeyException would mean, something with my key generator would be wrong. In that case, an exception indicates, that there is some bug in my key generator. Is there some way to handle it by the caller of the create method? I don't think so. So how will i handle it? I throw a RuntimeException which wraps the DuplicateKeyException and aborts the current execution. A top-level exception handler will catch this runtime exception and log it. If the execution has been initiated by some user interaction, the user will get some general error message. But at the end, its a bug in my key generator and there is no clean way to deal with this at runtime, but to log it and later fix it.

    So what could i do with the more general CreateException? It could be caused by some database problem? But if i can not create my entity bean, what shall i do?

    My point is, that in many cases, typical exception handling will just be very simple: abort current execution and log the exception. In all those cases a RuntimeException will do it. And it doesn't need to be some specific subclass of RuntimeException. At the end, i'm only interested in the line of code, which originally caused the problem, because this indicates some bug or environment problem (database transaction log full, etc.).

    So in many cases, checked exception are just forcing me to introduce the same code (which wraps them into a RuntimeException) again and again.

    The only useful cases for checked exceptions, i can imagine is, if there is some alternative action i can do to finish my operation successfully, or the exception is not that critical that i must abort my operation, so it can be ignored.

    I expect, that both cases are rather seldom. If this really is the case, i think the idea of getting just a warning from the java compiler instead of an error when not dealing with a checked exception would be a good idea.

    What do you think about this? Are those cases, where you really have to deal with checked exceptions that seldom?
    I would be very interested in some concrete real-life examples, where checked exceptions add some value.


    regards

    Thomas
  89. Examples needed[ Go to top ]

    <thomas>...where checked exceptions add some value. </thomas>

    Can't think of any.

    One thing that have not been mentioned is how badly exceptions are used in the standards library. One thing is that method signatures say one thing about exceptions, but the documentation states additional throw clauses. This is confusing. What's worse, however, is that exceptions in the JDK quite often indicate expected conditions, hence forcing your catch blocks to participate in your applications functional logic.

    For instance, having to handle a FileNotFoundException is stupid when opening a file. Not finding a file, in most cases, is not an abnormal program state. It is something your application should expect and deal with using normal programming idioms, such as "if(file.state != FileState.notFound) ..."

    Tiny digression: I frequently switch between .NET and Java these days. Switching back to .NET appears to become more and more pleasant (not mainly because of checked exceptions or the lack of it :-) If .NET one day becomes platform independent, through the mono project, perhaps... goodbye Java. Anyone else having the same feeling?
  90. I think we still need the checked exceptions.

    For one, I do not think unchecked exceptions will lead to any better programming practices than the checked ones. If you get lazy catching unchecked exceptions, it will be a hell trying to figure out what to do about 25 different unchecked exceptions coming from a method call that did not handle any exceptions and just let everything through. Checked exceptions would at least make you think about exception handling and not conveniently forget about it.

    Secondly, if your compiler warns about unchecked exceptions, which ones will you handle? How will you know what warnings you should be concerned about and what not? Some warnings you can dismiss, but some you should really handle, but I am thinking you will miss a couple. Imagine a program with 1000 warnings - take your pick.

    So, I think checked exceptions are still useful, and dismissing them entirely is a mistake. They at least give you a chance to communicate clearly what error cases there will be and you have to handle them on some level to compile your program. You can handle them clumsily or badly but you are handling them and not dismissing them.
  91. Dmitriy,

    I agree with you :)
    There are situation when checked exceptions are better, and others where throwing unchecked makes a lot of sense. And I certainly don't like to declare that I throw unchecked exception in my interfaces.

    Regards,
    Razvan Caraghin
  92. One of the major complaints I see with exception handling strategies is that the callee can not determine the context of the caller. One example is when a read of an object fails, for example, a file or a record in the database. Depending upon the caller's particular context, it may make sense to explicitly check for existence of the object, or the caller may not be able to handle the situation if the object is not present.

    I've begun to think that a caller should be able to specify how he wants exceptions returned to him. Callees would be oblivious to this - rather, it would be handled by the compiler (and possibly virtual machine). For example, given this callee method,

    Record readRecord( RecordId id ) throws RecordNotFoundException {
      // look up record
      // ...
      if ( recordNotFound ) {
        throw new RecordNotFoundException( "Unable to locate the record " + id );
      }
      return record;
    }

    ReadRecord could be called in one of two ways. The first style would be normal.

    void doStuff() {
      // Let the exception propagate, because I know
      // it would be something I can't handle
      Record r = readRecord();
      // ...
    }

    The second style would place the exception into a variable.

    void doStuff() {
      // Read the record, and if a RecordException is thrown, place it
      // into the declared variable, recordException
      Record r = readRecord() : RecordException -> recordException
      if ( recordException != null ) {
        // Tell the user there isn't such a record
      }
      else {
        // Do some processing
      }
    }

    This way, clients can use the return value / exception strategy which is most appropriate for their own context. It might even be possible to optimize the code generation so that exceptions "caught" in the second manner, don't generate a stacktrace, thus reducing the performance overhead in using exceptions. Implementing this language feature should be fairly trivial.

    God bless,
    -Toby Reyelts
  93. A few things[ Go to top ]

    Ok, a few things:

    RE: An example of a good exception

    You have an OrderManager, and a method placeOrder(). OrderManager.placeOrder() will throw an InvalidOrder exception, which has a getInvalidItems() method that returns the invalid order items that were rejected during placeOrder().

    Moral of story: custom checked exceptions are useful for storing exception specific details so that you can present better error information to the user.

    RE: Non-Checked exceptions
    I think that if everyone decided that all there exceptions were un-checked and they took out their exception handling blocks, they would find that their apps crash HARD. Why? Because, unchecked-exceptions doesn't mean that the exception won't happen! If an unchecked-exception is thrown, the current thread of execution stops, and the exception gets thrown up to the first handler that is found. If there is no handler, then that would be the main VM handler, and at that point, your whole app could die. If you changed your codde from:

    try
    {
      Logger.log("this was logged.");
    }
    catch (Exception e)
    {
      System.out.println("falied to log becase of excepiton: " + e.getMessage())
    }

    to:

    Loger.log("this was logged.");

    Then when you actually get an exception, the code stops right there and your applicaiton takes a crap. Is this what you want? No, of course not, even if you hate checked exceptions, you probably don't realize the fact that you are handling the exception is keeping your application stable. That's right: even if you catch any excepiton and report 'Action Failed!' at least your application still lives on to handle subsequent requests. I think this is a Very Good Thing (tm).

    That being said, I have my 'pass/fail' types of function calls throw Exception. I'm a baaaaaad boy.

    -Chris
  94. A few things[ Go to top ]

    Moral of story: custom checked exceptions are useful for storing exception specific details so that you can present better error information to the user.


    You could do the exact same thing with an unchecked exception.

    >
    > RE: Non-Checked exceptions
    > I think that if everyone decided that all there exceptions were un-checked and they took out their exception handling blocks, they would find that their apps crash HARD. Why? Because, unchecked-exceptions doesn't mean that the exception won't happen! If an unchecked-exception is thrown, the current thread of execution stops, and the exception gets thrown up to the first handler that is found. If there is no handler, then that would be the main VM handler, and at that point, your whole app could die. If you changed your codde from:
    >
    > try
    > {
    > Logger.log("this was logged.");
    > }
    > catch (Exception e)
    > {
    > System.out.println("falied to log becase of excepiton: " + e.getMessage())
    > }
    >
    > to:
    >
    > Loger.log("this was logged.");
    >
    > Then when you actually get an exception, the code stops right there and your applicaiton takes a crap. Is this what you want? No, of course not, even if you hate checked exceptions, you probably don't realize the fact that you are handling the exception is keeping your application stable. That's right: even if you catch any excepiton and report 'Action Failed!' at least your application still lives on to handle subsequent requests. I think this is a Very Good Thing (tm).
    >

    To me the unchecked example is much better. It is extremely annoying to have to surround all seemingly innocuous method calls with a try..catch block - especially when there is nothing that I can do when an exception occurs.

    One approach that I've been using is to implement a policy that all unchecked exceptions must extend from a domain-level (application, framework, etc...) exception. Then make sure that there is a top-level handler for the domain-level exception. This will eliminate the possiblity that your application will 'take a crap' as you put it. Also, now I have a choice as to whether or not I want to handle the exception where it happens or let it propagate to the top-level handler.

    In your checked exception sample, what happens if you are calling a number of methods that may throw Exception?

    try {
      Logger.log( "this may be logged" );
      someObject.executeMethodThatMayThrowException();
      Logger.log( "this may be logged" );
    }
    catch( Exception e ) {
      // Which method threw the exception? Not sure? Guess I'll just log it and
      // continue.
      System.out.println( "Some unexpected exception occurred..." );
    }

    Or do you suggest breaking up the calls into separate try...catch blocks?
     
    try {
      Logger.log( "this may be logged" );
    }
    catch( Exception e ) {
      System.out.println("falied to log becase of excepiton: " + e.getMessage())
    }

    try {
      someObject.executeMethodThatMayThrowException();
    }
    catch( Exception e ) {
      System.out.println( "Failed while excecuting method, reason: " +
                           e.getMessage() );
    }

    try {
      Logger.log( "this may be logged also" );
    }
    catch( Exception e ) {
      System.out.println("falied to log becase of excepiton: " + e.getMessage())
    }

    Either way, the code is less readable and chances are that the Logger will have already printed a message out to the console when it encoutered the condition that caused the exception to be thrown in the first place.
  95. A few things[ Go to top ]

    \Parrone\
    [...sample code of one try catch block vs. many...]

    Either way, the code is less readable and chances are that the Logger will have already printed a message out to the console when it encoutered the condition that caused the exception to be thrown in the first place.
    \Parrone\

    Um....your example has nothing to do with checked exceptions. An unchecked exception exhibits _exactly_ the same problem.

    \Parrone\
    One approach that I've been using is to implement a policy that all unchecked exceptions must extend from a domain-level (application, framework, etc...) exception. Then make sure that there is a top-level handler for the domain-level exception. This will eliminate the possiblity that your application will 'take a crap' as you put it. Also, now I have a choice as to whether or not I want to handle the exception where it happens or let it propagate to the top-level handler.
    \Parrone\

    What if you miss a handler in one of your threads? There's no way to know that you missed it.

    What if the underlying low-level code adds a new unchecked application exception that doesn't extend an already covered domain exception? Again - there's no way to know:

       - An exception has been added to low-level code
       - there's no handler for that exception

    The end result is that your code can very, very easily fail, and it's very, very difficult to find out that fact.

        -Mike
  96. A few things[ Go to top ]

    <quote>What if the underlying low-level code adds a new unchecked application exception that doesn't extend an already covered domain exception?</quote>

    This would represent an irresponsible change in a library--it's an issue of responsible library evolution more than checked vs unchecked exceptions. It would also be destructive from a library if it regularly required all callers to catch new checked exceptions, thereby breaking all existing code using it. In either case, it's vital to have a well-defined exception hierarchy and avoid inventing new top-level exceptions. For example, as Yann pointed out, the Spring Framework's DataAccessException--the base of its data access exception hierarchy--will always be a common superclass for Spring's DAO exceptions. Below this there's a hierarchy that's also quite stable. New exceptions are added only at a finely detailed level, in which case they'll be caught by existing handlers, and will not require any code changes.

    Btw, I would like to dispel the impression that I'm completely against checked exceptions. I think they're overused, but still valuable.

    Regards,
    Rod
  97. A few things[ Go to top ]

    <mike>
    What if the underlying low-level code adds a new unchecked application exception that doesn't extend an already covered domain exception?
    </mike>
    <rod>
    This would represent an irresponsible change in a library--it's an issue of responsible library evolution more than checked vs unchecked exceptions. It would also be destructive from a library if it regularly required all callers to catch new checked exceptions, thereby breaking all existing code using it
    </rod>

    I agree with you, Rod, that whatever changes a library makes it should preserve backward compatibility. However, any reasonable application utilizes multiple libraries. Every one of those libraries has its own exception set. Now, suppose that method M1 was calling a library L1 which threw *runtime* exceptions E1 and E2. Down the method call graph, there are methods M2 and M3 that call M1, and methods M4 and M5 that call M2 and methods M6 and M7 that call M3. This call graph, I believe, is extremely common and looks like following:
                                    M1
                                  / \
                                M2 M3
                              / \ / \
                            M4 M5 M6 M7

    So, every method in this graph, from M1 to M7, throws 2 *runtime* exceptions: E1 and E2. Now, suppose that method M1 decides in addition to utilizing library L1 to also utilize library L2 which throws exception E3. Since exceptions E1, E2, and E3 are runtime, you have to change exception handling in M4, M5, M6, and M7. Chances are that you will miss a method or two, therefore, rendering your code going in production with a few unhandled exceptions.

    Also, if you were relying on Javadoc documentation for knowing which method throws which exception at any time, a simple change described above would require Javadoc changes in methods M2, M3, M4, M5, M6, M7. I believe it would be quite naive to think that a developer (even a good one) would never miss one or two exceptions in Javadoc. Hence, you end up with wrong documentation which, I would argue, is equally dangerous as forgetting to handle an exception.

    However, if E1, E2, and E3 were *checked* exceptions, compiler would immediately point out the places where changes need to be made which will lead, in my opinion, to a more robust product.

    For the sake of the example, please assume that E1, E2, and E3 are recoverable exceptions that may occur in production.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  98. A few things[ Go to top ]

    <dmitriy>
    For the sake of the example, please assume that E1, E2, and E3 are recoverable exceptions that may occur in production.
    </dmitriy>
    I don't disagree with your example. If we assume these are recoverable exceptions I'd happily make them checked. I advocated unchecked exceptions for fatal conditions, or those that ae hardly ever recoverable.

    Regards,
    Rod
  99. A few things[ Go to top ]

    <rod>
    I advocated unchecked exceptions for fatal conditions, or those that are hardly ever recoverable.
    </rod>

    Then we are *almost* in agreement ;-). The only problem is determining what a fatal or a hardly ever recoverable exception is. What can be fatal or hardly-recoverable in your experience, may be non-fatal or very recoverable in experiences of others. When writing a library or any kind of reusable API, you must not make any assumptions on who will be using it. That's why, if the exceptions E1, E2, and E3 in my example are *runtime*, then some portion of developers would have to go through *a living hell* when using the API.

    On the other hand, there are certainly cases when you know for sure that exception is *fatal*, like (please forgive the simplicity of the example) a wrong variable passed into a method. In this case, you can throw a *runtime* exception (IllegalArgumentException, for example) and it would be totally appropriate.

    Best regards,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  100. A few things[ Go to top ]

    There's a tradeoff here. I think it's a greater evil to force all callers to deal with a 99.9% fatal exception. It does obscure code to no purpose, and it usually results in the "wrap and throw" game that produces reams of exception classes at different abstraction layers, again for no gain.

    The 0.1% can read the Javadoc and write code to catch that exception. There's a whole lot of things to know about invoking methods--assumed state etc--and compile-time checking isn't a panacea. Usually they will want to catch it immediately in the calling method, which knows about the relevant abstraction level. This approach does work in other langauges.

    In many of the cases where I use unchecked exceptions I'm not even convinced there's a 0.1%, and I don't want to complicate use of an API in case someone ever comes up with a really weird use for it. If they have an atypical context, they also have the responsible for ensuring they understand the relevant method contracts.

    I think this approach works well in JDO.

    Rod
  101. A few things[ Go to top ]

    <rod>
    I think it's a greater evil to force all callers to deal with a 99.9% fatal exception.
    </rod>

    I still don't get it.

    Assuming that all clients do the right thing when they can't handle an exception (declare it in their throws clause), the whole debate boils down to this:

    - Checked exceptions force you to have at least one catch block in your call chain.
    - Unchecked exceptions force you to have at least zero catch block in your call
    chain.

    I fail to see why readability is so much impaired by this difference.

    <rod>
    The 0.1% can read the Javadoc and write code to catch that exception
    </rod>

    If I have to choose, I will pick statically checked code over javadoc-checked code without a second of hesitation...

    --
    Cedric
    http://beust.com/weblog
  102. A few things[ Go to top ]

    <cedric>
    Assuming that all clients do the right thing when they can't handle an exception (declare it in their throws clause), the whole debate boils down to this:

    - Checked exceptions force you to have at least one catch block in your call chain.
    - Unchecked exceptions force you to have at least zero catch block in your call
    chain.

    I fail to see why readability is so much impaired by this difference.
    </cedric>

    Declaring all those checked exceptions in your throws clauses on all application layers leads to broken abstraction: Why should a high-level business service or even a web controller have to throw and thus know about SQLException, for example, especially if it is just able to treat it as fatal? This is one thing that exception hierarchies like Spring's DataAccessException achieve: Abstraction also in terms of exceptions - from the underlying persistence mechanism, in this case.

    Juergen
  103. A few things[ Go to top ]

    <rod>
    There's a tradeoff here. I think it's a greater evil to force all callers to deal with a 99.9% fatal exception. It does obscure code to no purpose, and it usually results in the "wrap and throw" game that produces reams of exception classes at different abstraction layers, again for no gain.
    </rod>

    Assumptions, assumptions, assumptions...

    *99.9%*... Hm... I wonder how we came up with this number... If there was a survey, I certainly did not participate in it ;-) Using your logic, I might, as well, claim that the ratio is 70% or 50% and you won’t be able to prove me wrong. As a matter of fact, if you take this thread into consideration, there is about 50/50 split on whether your so called *hardly-recoverable* exceptions should be runtime or checked. So by making your *trade-off*, you force a significant number of developers into going through javadoc hell.

    Hope this helps,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  104. A few things[ Go to top ]

    On the other hand, there are certainly cases when you know for sure that exception is *fatal*, like (please forgive the simplicity of the example) a wrong variable passed into a method. In this case, you can throw a *runtime* exception (IllegalArgumentException, for example) and it would be totally appropriate.


    Dmitriy,

    I'm trying to understand your reasoning. Can you give me a real example where you are 100% sure (not 99.9%) that the exception is not recoverable?
  105. A few things[ Go to top ]

    <Pato>
    I'm trying to understand your reasoning. Can you give me a real example where you are 100% sure (not 99.9%) that the exception is not recoverable?</Pato>

    In my experience, the only cases when I am sure that an exception is 100% not recoverable is when some contract of API is violated. Like aguments into the method are of the wrong range or value, or some other method precondition is not met. If sequence of method calls is wrong (i.e. misuse of API), then it's also a good candidate for runtime exception. In this cases, developer most likely will be able to reuse exceptions already provided in JDK (like, IllegalArgumentException or InsupportedOperationException), but sometimes it may be appropriate to create an api-specific runtime exception.

    Hope this answers your question,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  106. I might as well lob this into the debate now as much as any other time ;-)

    I've been working or a couple of decision diagrams. One to decide whether to throw an exception and, if so, what type to throw. The other to help with handling checked exceptions (i.e. what to do what you receive them!).

    These (together with a couple of my favourite exception anti-patterns) can be found at:

    http://www.jiffle.net/development/Exceptions.html

    Constructive comments are extremely welcome.

    I'll also try to include the diagrams on this page (bet this doesn't work!)

    <img src="http://www.jiffle.net/img/throwing_exceptions.png" width="738" height="624">

    <img src="http://www.jiffle.net/img/handling_checked_exceptions.png" width="774" height="641">

    /david


  107. this is great stuff! thanks for sharing.
  108. This thread has been very interesting to read and have opened up my mind quite a bit about how to handle exceptions in my applications. I have read the arguments from both sides but still tend to agree with Cedric and David about the use of checked exceptions.

    One of my main arguments is that if I use a library (or any other abstracted logic) in my application I want to know the contract for using the library and its functionality. This most often (if it is a well-designed library) will let me upgrade the library functionality without having to worry that my own application logic breaks.

    If the library makes use of checked exceptions for its API I will only have to do a recompile of my application against the new API to see if the contract has changed (which won't happen very often in a well-designed library).

    If the library made extensive use of unchecked exception to report regular exceptional conditions in the library logic I would have to read JavaDoc (and hope it was up to date) for every API I use and then compare the possibly new exceptions to the ones I already handle to make sure my application won't break in some obscure way.

    Of course I have some way of handling exceptional conditions based on an unchecked exception but I don't want to find out about a new API contract by seeing the com.whatever.NewRuntimeException showing up in my log. This will make me go in and adapt my application to possibly handle this new exception in some part of my code if possible and then wait for the next surprise and adapt again.

    My view of exceptions is that checked exceptions are anticipated possible errors that a client can make a decision about how to handle. The handling of the exception is dependant upon the clients context and environment and the thrower of the exception can't make assumptions about that context (as have been pointed out above).
  109. In conclusion...[ Go to top ]

    Look at this another way....

    When an error happens it ends in one of two ways -

    * the current unit of work is aborted and execution ends up with a top-level handler ('failure' state)
    * the error is recovered and the program completes the unit of work ('normal' state)

    Before this is resolved, one way or another, the program may pass the error around amongst code participating in the activities leading up to the error. Let us call this phase 'exception' state.

    It is a transitional phase, which should resolve to either normal or failure state.

    This is what checked exceptions allow and enforce: They should involve the participants in the error situation in the attempt to resolve it. And that is why it is important that they are checked - because, as participants, they must know that they are involved in the process, hence the requirement that their participation be checked.

    Those who eschew checked exceptions are using a strategy that ignores this period of attempting to recover. They put the system directly into failure mode without consulting the rest of the participating code.

    Conversely, those who never throw unchecked exceptions are never actually acknowledging failure, so to speak. They are involving all and sundry in the attempt to recover, until they finally run out of options.


    I really believe that checked exceptions offer a third (transitional) state of attempting to recover from an error, which it is important to utilise if robust applications are to be written.

    /david
  110. In conclusion...almost[ Go to top ]

    David,

    I really like this description, utilizing normal, exception, and failure states (and I agree with the general mantra of "Both checked and unchecked exceptions have their places" expressed by both sides in this thread). However, there's one additional aspect missing from your treatment: the scope of the exception phase.

    Everybody appears to agree that, in some cases, the scope of the exception phase must extend outside of the class in which the exception occurred (source? exceptor?) and involve other participants up the stack (targets? exceptees?), while in other cases, the source class already knows enough to deem this a failure (e.g., OutOfMemoryException). The debate seems to hinge around when (and how far) to extend that scope, with the resultant impacts upon compile-time checks and maintainability.

    And, on a side note, it's interesting that this debate typically resurfaces around the same J2EE thorn, RemoteException. I would argue that there probably are use cases where a business function can recover from a failure to complete a portion of its processing (as implemented by a particular, unavailable EJB), but I would also probably argue that hinging your design on catching and recovering from RemoteException in such a case is potentially a poor design. (If it's unnecessary and won't be retried, why tightly couple it to begin with? If it will be queued and retried, why not use asynchrony--e.g., a Message Facade--to begin with? If there are potential alternate resources to use, you probably don't want that inside of your business logic. Etc., etc.)

    cramer
  111. In conclusion...almost[ Go to top ]

    <steve>
    However, there's one additional aspect missing from your treatment: the scope of the exception phase.
    </steve>



    Yep, absolutely agree. (Apologies for the delay replying - been away!)

    I've not yet fully thought this one through. Certainly the maximum scope of the exception phase is clear... where the exception ceases to be meaningful to the calling code, then either a failure has to be declared (usual case), or the exception converted to another checked exception.

    When would the second case be used? I guess the case of something like a BusinessValidationException, where the checked exception represents a path to a known recovery mechanism, such as re-displaying the data entry page with specific validation failure information. (This can be characterised as a specific type of the exceptional state, which eventually recovers to a normal state at a higher level handler.)

    As for the minimum, well that would (I'm afraid) depend on the usage pattern that was expected by the code being called. I've had some thoughts about that which I'll try to discuss in another post...

    /david

    PS: I was interested in your note on Remote Exception, but want to think through any comments a bit more before posting!
  112. In conclusion...[ Go to top ]

    <dave>
    This is what checked exceptions allow and enforce: They should involve the participants in the error situation in the attempt to resolve it. And that is why it is important that they are checked - because, as participants, they must know that they are involved in the process, hence the requirement that their participation be checked.

    Those who eschew checked exceptions are using a strategy that ignores this period of attempting to recover. They put the system directly into failure mode without consulting the rest of the participating code.

    Conversely, those who never throw unchecked exceptions are never actually acknowledging failure, so to speak. They are involving all and sundry in the attempt to recover, until they finally run out of options.

    </dave>

    Nice conclusion, Dave, I could not have said it better. By the way, I enjoyed reading your replies and I believe you defended your point quite well.

    Needless to say, I entirely share your opinion.

    Best regards,
    Dmitriy Setrakyan
    Fitech Labs, Inc.
    xNova™ - Service Oriented Architecture for Java and .NET
  113. In conclusion...[ Go to top ]

    I liked the way you put it.

    Put another way, if you only use unchecked exceptions, you cannot be sure that the unchecked exception that you are trying to handle (i.e. recover from) is coming from the task that you asked the callee to do, or some obscure sub-task 200 levels down.

    With checked exceptions, you know that the exception is part of the result of the callee itself, because it is an explicit part of the callee's interface. Thus you are forced to deal with it. (This is why declaring "throws Exception" can be a very dangerous design decision.)

    When checked exceptions are overused, that beautiful "forced to deal with it" approach will naturally degrade to "a pattern of eating exceptions" and/or "a pattern of declaring all methods in the entire app with the complete set of possible checked exceptions". I've witnessed both.

    Hence, the requirements of good design, and balanced (correct) use of checked and unchecked exceptions.

    Peace,

    Cameron Purdy
    Tangosol, Inc.
    Coherence: Easily share live data across a cluster!
  114. Some time ago I read an article written by Dr. Heinz Kabutz on this subject (against checked exceptions) and sent him an email stating my disappointment in his position. He replied and included Bruce Eckel on his reply, and Bruce added his own email, and this was my response. Let me know if you'd be interested in the whole correspondance. And if you don't want to read all the following, the gist of it is that there really needs to be a programmatic way to make sure that exceptions are indeed being handled and a way to see where that is taking place.

    <me>
    Thanks for your thoughts. I had actually read your article online about checked exceptions long before I responded to Dr. Kabutz, so I am aware of the option to bypass the checked exceptions by wrapping them in RuntimeExceptions. I think, though, that it doesn't directly address the point I was making. I think that there should be some programmatic way, at compilation, to check to see that you are, indeed, trapping the different possible errors that exist. I maintain that a better option would be to have, perhaps, all exceptions be declared, but allow for different levels of compilation. For example, you could have a compiler flag that would, with different values, allow compilation to proceed ignoring any uncaught exceptions, or allow compilation ignoring only uncaught runtime exceptions (the current behaviour), and so on and so forth. I strongly believe that forcing programmers to declare which exceptions their code can throw is very important. Perhaps the current semantics and implementation could be tweaked to make it better, but I think a language (like C#) that has no way of declaring exceptions in the code is bound to lead to less robust code.
    </me>

    In a nutshell, good software engineering is about (most importantly) making sure it won't break and the earlier in the development process you can do that (say, compilation vs runtime) the better. Will my suggestion ever make it into Java? Probably not, but if it could get incorporated into future languages I think we'd be a lot better off than C#....