Would You Like Checked or Unchecked Exceptions With That?

Blogs

Blogs: Would You Like Checked or Unchecked Exceptions With That?

  1. Are checked exceptions in Java code litter? That is this opinion expressed by Eric Burke in his blog on why unchecked exceptions are better. He notes that some major frameworks including Spring, EJB3 and Hibernate have moved to eliminate checked exceptions from their implementations. The blog also goes on to claim that the inclusion of checked exceptions is a violation of encapsulation in that it exposes information about the implementation. The solution to this problem is to catch, wrap and re-throw the exception. As Eric puts it,
    That’s really bad because the implementation - Hibernate - is bleeding through the interface. You don’t want your application logic to know your DAOs are implemented using Hibernate. So you try and fix it like this:


    public void doSomething() {
        try {
            ...
        } catch (HibernateException ex) {
            ... now what?
        }
    }
    Does moving from a checked exception to an unchecked exception model really solve this problem or does it just hide it.

    Threaded Messages (23)

  2. Put them in throws anyway[ Go to top ]

    Either checked or not, all exceptions that a method can throw could be put in throws clause.
    For checked ones compiler will check if caller handles them, for unchecked we get self-documenting code.
  3. It depends on application[ Go to top ]

    I think in simple CRUD web application it is good idea to use unchecked exception, because they are happen only if everything is broken. I don't think it is possible to do something meaningful when database dies or when database schema is incorrect. They are definitely RuntimeException.

    But when you writing more complex application which has complicated interface and has to report many kinds of errors it is good idea to use checked exception because in other ways in is hard to find situtation when operation is terminated silently and no information is displayed to user. In this case compiler will check exception annotation and if you missed some of this exceptions you code won't compile.

    There are a lot of Java libraries which misuse checked exceptions. For example many methods in JDOM throws IOException, JDomException, and it is very hard to write exception handling code for all of them.
  4. I agree that checked exceptions are overused in Java libraries. A perfect example is InterruptedException on sleep(). I mean, 99% of the time, you could care less if the thread was interrupted while sleeping for a second. Why should I have to add a catch block every time I call sleep to handle this corner-case?

    Having said that, I take issue with the first example in the article. 1. Don't throw a checked exception from doSomething(). 2. If you doSomething() is from some library you don't have control over, why the hell are you calling it from an anonymous listener? That's just bad GUI code. It's almost surely an instance of embedding business or application logic in GUI components. 3. Does the author think that letting the exception fall into the caling Swing class is a good practice? Does he expect Swing to know what to do with this?

    I get really annoyed by people complaining about how things that can be used to good effect (like checked-exceptions) make it hard to write crap slop-code.

    How many times have you had a bug because an unexpected erro condition was not handled properly? Using checked exceptions can really help to avoid surprises. The problem isn't check exceptions, it's the use of checked exceptions when unchecked exceptions are more correct.
  5. I agree that checked exceptions are overused in Java libraries. A perfect example is InterruptedException on sleep(). I mean, 99% of the time, you could care less if the thread was interrupted while sleeping for a second. Why should I have to add a catch block every time I call sleep to handle this corner-case?

    The real problem is that I've never seen an application handle the InterruptedException correctly. Never. Nobody seems to understand what it means.

    Peace,

    Cameron Purdy
    Tangosol Coherence: Clustered Shared Memory for Java
  6. I agree that checked exceptions are overused in Java libraries. A perfect example is InterruptedException on sleep(). I mean, 99% of the time, you could care less if the thread was interrupted while sleeping for a second. Why should I have to add a catch block every time I call sleep to handle this corner-case?
    The real problem is that I've never seen an application handle the InterruptedException correctly. Never. Nobody seems to understand what it means.

    Does that include yourself?

    According to the API it's "Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread."

    In your average Java application, this method is never called. I don't know that it is called by anything in the VM or otherwise but if it were, what exactly should one do when this exception is thrown and there is no specific requirement for interrupting threads? Blow up? Use clarivoyant AI routines to determine what the intention of the calling thread might be?

    Do you have more information on what a catch block for this exception should look like in an application where interrupt is not called (at least not by the application's logic)? The API sure doesn't provide any helpful hints.
  7. Thread InterruptedException[ Go to top ]

    I agree that checked exceptions are overused in Java libraries. A perfect example is InterruptedException on sleep(). I mean, 99% of the time, you could care less if the thread was interrupted while sleeping for a second. Why should I have to add a catch block every time I call sleep to handle this corner-case?
    The real problem is that I've never seen an application handle the InterruptedException correctly. Never. Nobody seems to understand what it means.
    Does that include yourself?According to the API it's "Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread."In your average Java application, this method is never called. I don't know that it is called by anything in the VM or otherwise but if it were, what exactly should one do when this exception is thrown and there is no specific requirement for interrupting threads? Blow up? Use clarivoyant AI routines to determine what the intention of the calling thread might be?Do you have more information on what a catch block for this exception should look like in an application where interrupt is not called (at least not by the application's logic)? The API sure doesn't provide any helpful hints.

    Actually, the Sun Core Java books provide several examples of what you should do in this case. Depending on the application, there are a number of different things you might want to do, ranging from ignoring it to causing the application to halt gracefully. Basically, if you do not know what to do with this exception, then you have no business coding threads. Note that the API documents are very good about telling you what a method does, but lousy about telling you how to use them.
  8. Thread InterruptedException[ Go to top ]

    Actually, the Sun Core Java books provide several examples of what you should do in this case. Depending on the application, there are a number of different things you might want to do, ranging from ignoring it to causing the application to halt gracefully.

    Now can you explain what irony is?
    Basically, if you do not know what to do with this exception, then you have no business coding threads. Note that the API documents are very good about telling you what a method does, but lousy about telling you how to use them.

    If this is your idea of an informative answer, you have no business answering questions, especially those not directed at you.

    I never mention anything about 'writing a thread' (however you want to define that: all Java code runs in threads) BTW.
  9. I agree that checked exceptions are overused in Java libraries. A perfect example is InterruptedException on sleep(). I mean, 99% of the time, you could care less if the thread was interrupted while sleeping for a second. Why should I have to add a catch block every time I call sleep to handle this corner-case?

    The real problem is that I've never seen an application handle the InterruptedException correctly. Never. Nobody seems to understand what it means.

    Does that include yourself?

    At one time, yes. A certain app server (ATG) taught me the lesson the hard way, that InterruptedException has a real meaning and must be dealt with correctly. For example, when you are interrupted, unless you explicitly were designed to expect such a thing, you need to set the interrupted flag back again (or the interruption is lost), e.g.
    try
        {
        ..
        }
    catch (InterruptedException e)
        {
        Thread.currentThread().interrupt();
        throw new WrapperException(e);
        }

    Only if you are the place designed to handle the interruption (if there is such a place) would you _not_ call interrupt() on the current thread.

    Following that with a runtime exception thrown up the chain can be a good way to unwind. If you don't handle it correctly, you may just find your threads missing (and not having cleaned up after themselves correctly). Yes, that's right, ATG will just kill your threads (whack!) if you don't handle the interruption correctly.

    Peace,

    Cameron Purdy
    Tangosol Coherence: The Java Data Grid
  10. Does that include yourself?
    At one time, yes. A certain app server (ATG) taught me the lesson the hard way, that InterruptedException has a real meaning and must be dealt with correctly. For example, when you are interrupted, unless you explicitly were designed to expect such a thing, you need to set the interrupted flag back again (or the interruption is lost)

    That's good information and I appreciate the info, however, I don't think it really applies to what I am asking.

    Let's say I am writing a simple non-J2EE application with a simple thread that does some sort of periodic activity with a sleep. There is nothing in the application that will ever call interrupt on this thread. Stopping the thread either occurs when the VM is shutdown or through a API method.

    I suppose I can put that code in my catch block, but I really don't think it matters. The real question (why I brought it up) is that for a lot of applications, the Thread API could handle this itself. If I need to add special interruption handling to my code, they could provide a second method that throws the exception or have created an InteruptionHandler interface that we could implement.

    If I'm incorrect in this, please enlighten me.
  11. If I'm incorrect in this, please enlighten me.

    I can't speak for anyone else. I know that the libraries that we provide get used in ways we never expected, so we have no choice but to "do it right".

    For single-threaded apps, handling these conditions is just a nuisance.

    The grey area is the code in-between "library" and "app" .. will it get re-used in some other environment? Will the current environment change? etc.

    Peace,

    Cameron Purdy
    Tangosol Coherence: Clustered Shared Memory for Java
  12. If I'm incorrect in this, please enlighten me.
    I can't speak for anyone else. I know that the libraries that we provide get used in ways we never expected, so we have no choice but to "do it right".For single-threaded apps, handling these conditions is just a nuisance.The grey area is the code in-between "library" and "app" .. will it get re-used in some other environment? Will the current environment change? etc.Peace,Cameron PurdyTangosol Coherence: Clustered Shared Memory for Java

    The other side of that argument is that you can't possibly predict what that future usage is so writing code to support it is an exercise in futility. For example, let's say someone does decide to call interrupt on my thread in the future. Does this future coder want to stop the thread? Does this coder just want to cut the sleep short and let it continue on it's merry way? My crystal-ball is in the shop.

    It also doesn't address my point (the only one relevant to the thread) that the API could have provided a way to handle Interrupts in a way that doesn't burden every developer with knowing this (demonstrably) esoteric information. The default behavior could 'do it right' and only developers that have a need for special handling of interruptions would be bothered with it.
  13. The other side of that argument is that you can't possibly predict what that future usage is so writing code to support it is an exercise in futility.

    I'm not with the XPers on this one. You _can_ save a lot of aggravation with a little bit of forethought and careful design.
    It also doesn't address my point (the only one relevant to the thread) that the API could have provided a way to handle Interrupts in a way that doesn't burden every developer with knowing this (demonstrably) esoteric information. The default behavior could 'do it right' and only developers that have a need for special handling of interruptions would be bothered with it.

    I'm 100% with you on this. And you're right: It's the important lesson to be learned from this.

    Peace,

    Cameron Purdy
    Tangosol Coherence: Clustered Shared Memory for Java
  14. The other side of that argument is that you can't possibly predict what that future usage is so writing code to support it is an exercise in futility.
    I'm not with the XPers on this one. You _can_ save a lot of aggravation with a little bit of forethought and careful design.

    I'm not arguing that there is no way to prepare for the future but that it's not possible to make code support future requirements without changes. The best you can do is make your code easily extensible or easily changeable.

    In this case (and I could be wrong) I think it's very difficult to handle the interruption (that should never occur) in a way that will be sure to make a future requirement happy. Prehaps there is a handling that is quite likely to do so or a design that allows for extensible handling but then I have to question the value of investing the time to design and implement a feature that may never be used.
  15. Agreed, I much prefer checked exceptions so that I know how some code may break and have appropriate cleanup/recovery code, rather than having to guess. It annoys me that I have to add a Throwable catch (in addition to other catches) in lots of code to compartmentalise data processing and catch any unknown exceptions or errors, to log them (critical for debugging live systems) and recover properly for further processing. An example is a business client wanted all the good data to go through a system and was annoyed when a single bad (spurious) data item caused a process to halt due to exception fall-through, so I have to use catch ALL exceptions in each layer of the process.

    IMHO unchecked exceptions are a curse in many cases, they just hide the fact that much production code still needs try-catch-finally to work correctly.
  16. Agreed, I much prefer checked exceptions so that I know how some code may break and have appropriate cleanup/recovery code, rather than having to guess. It annoys me that I have to add a Throwable catch (in addition to other catches) in lots of code to compartmentalise data processing and catch any unknown exceptions or errors, to log them (critical for debugging live systems) and recover properly for further processing. An example is a business client wanted all the good data to go through a system and was annoyed when a single bad (spurious) data item caused a process to halt due to exception fall-through, so I have to use catch ALL exceptions in each layer of the process.IMHO unchecked exceptions are a curse in many cases, they just hide the fact that much production code still needs try-catch-finally to work correctly.

    It breaks my heart to read posts like this. I wish you had at least first read what some smart people have written on the subject before stating this... Like the blog in question, for instance... Do people realize that just a decade ago - before Java - software engineers could not be expected to assume that there might be modules that NEVER fail! Everyone took for granted that ALL errors had to be caught and handled - always. Seriously, isn't there ALWAYS a possibility that something may not work? Of course! You don't need the compiler to tell you that, do you? Hmmm... do you really??? (Then, I hope you're not working for NASA, or elsewhere where people's lives may depend on your code.) Now, here comes Java with its checked exceptions, and produces generations of zombi programmers whose brain seems to completely shut off when it comes to error-handling. Okay, just catch the ones that the compiler tells you to catch - and move on... How do we know that the declared checked exception covers all possible errors that may occur under the hood of the given method? What most people are trying to do really belongs in the finally block, or at the safety net somewhere in a centralized location. So, why pollute layers and layers of code with useless try/catch's and 'throws', unnecessary and harmful contracts. Let's see... In the real world projects... Checked exceptions do not work with frameworks (because the latter need to be generic and flexible and checked exceptions force the implementation details onto the API clients.) They don't work with interfaces and make true polymorphism impossible. They break encapsulation. They are evil when it comes to scalability and versionability. They create a false sense of security and make developers forget to handle ALL errors in additoion to the declared checked exceptions. They promote loopholes for mishandling the very checked exceptions that have indeed been declared - you know what developers do just to silence the compiler and move on... In other words, they encourage developers to code poorly, which is the opposite to what the Java authors tried to achieve... And, finally, in 99% of all cases they don't even need to be (and can't be) handled at all until they reach the outmost layer of your application where most of them end up handled generically anyway. The list can go on and on... Even if there is a tiny positive use for checked exceptions, is it really worth it all the nightmare they have introduced? What do you do to make checked exceptions work with interfaces, for instance? You wrap them in a meaningless "MyInterfaceException". That exception will hide all the subclasses that your implementations throw and you can safely declare that your interfaces methods throw that wrapper exception. But, guess what, the compiler will never catch the _wrapped_ exceptions. So, you've just disabled the "checked" quality of your exception. Now, the only meaning it carries is... the reminder that _something_ may not exactly work within a class that implements your interface. Shouldn't you have assumed that anyway? Ahhhh... I know these discussions are useless. At this point, it all boils down to the egos of those who have used checked exceptions for years without questioning their value, possibly, enforcing those practices on others, and now simply are too proud to admit that there still may be things for them to learn and re-evaluate. Nothing shameful about that, by the way. ;)

    Peace...
  17. I certainly think there is a place for checked exceptions. Consider the authentication scenario -- consider the following:

    public User authenticate(String username, String password) throws InvalidCredentialsException;

    Chances are a caller can and will want to handle this in some way. But it is not the normal condition -- it is "exceptional". In my mind, this is a good practice and perfectly reasonable code. The problem is that we have always been taught to extend "Exception"; when we should have been taught "Extend RuntimeException if it's unreasonable to think that the exception can be recovered from, otherwise extend Exception". Makes me think that it might be cool if we could construct an exception indicating if it's to be checked or not ...

    -Bill Siggelkow
  18. The example of an 'InvalidCredentialsExcepton' (post #191884) illustrates the essence of what is wrong with the all too common misunderstanding and misuse of exeptions.

    Regarding a hypothetical authentication failure, the post says: "a caller can and will want to handle this in some way. But it is not the normal condition -- it is "exceptional". "

    However, this view is flawed: any authentication service has as its "normal" duties the responsibility not only to allow credentialed access, but also to deny uncredentialed access. There is nothing exceptional about an access attempt with invalid credentials. This is quite within the 'normal' semantic realm of an authentication services' responsibility to handle. Using the language syntax of exceptions for this case may be cute, but it is deeply incorrect.

    A subsequent post (#191901) re: Proper Layering is quite relevant. Most of the pathological use of exceptions in Java reflects design laziness, and is an abuse of a language feature which has a very limited scope of proper usage: for those situations which break the abstraction a given layer or service presents in such a manner that the entire context of the contract doesnt hold.

    And there really are very few such situations, and they do not include domain logic which has a subjective feel of not being 'normal'. The authentication example shows a bias toward one of the possible outcomes of an access attempt, and treating it as an exception shortchanges the clients of that service.

    The post (#919890) about Checked Exceptions and Contracts gets a bit closer. Yes, contracts should be explicit. And his point about checked expceptions and piece of mind is good, if one is stuck in an environment where exceptions are the rule. But ultimately it is still slightly off the mark.

    Any consumer of a class or method which throws exceptions related to the semantics of the problem domain should translate those cases into meaningful actions or meaningful, documented results -- meaningful in the semantic domain of the user or client of that service. In that light, the opening example of Hibernate leaking through was relevant.

    To those who think there is someting 'modern' about the language feature of exception syntax which therefore makes it better, they should consider portability and deployment issues, distribution of logic across tiers, and in what is truly the 'modern' environment, across languages and platforms.

    Yes, explicit contract is a good thing. Bending a syntactic construct for the wrong purposes is not.

    Like the 'goto' of a bygone era, just because a language syntax exists is not a good reason to use it.
  19. I agree...

    1. I would only add that explicit contracts are NOT ALWAYS a good thing. In fact, a component (a method, a service, etc.) has no business of telling its client what to do with the results of the component's execution. handling errors is unquestionably the responsibility of the client that uses the component. And it must be a crucial part of the client's design - instead of a hack in response to the compiler's complaint.

    2. Checked exceptions are totally incompatiple with... polymorphism. That's it! That should be the end of the discussion! Just look at the commonly used Command pattern and all those useless "MyCommandExceptions" that hide numerous useless specific exceptoins for the particular command implementatinos. Need I say more?

    3. Checked exceptions break one of the most important original principles of TRY/CATCH (as introduced in C++) - that is handling the error in a centralized place away from the error source, wherever it is most appropriate per the system _design_.

    The crucial word that everyone seems to be forgetting in all discussions about exceptions is DESIGN. Error handling must be DESIGNED, which means that you code your application so that NO errors break it at all, you put safety nets, centralized and localized as much as possible, and you do research the API you are using before you use them! Indeed, people talk about and treat errors in Java programs as an afterthought, something that they are only reminded of when the compiler throws a message in their face. That's why there are thousands of Java developers out there who honestly believe that runtime exceptinos are _designed_ to abruptly abort the applications, while checked exceptions are the only ones that are programmatically handled. That has become a curse for many many projects, and there is no end to this nightmare in sight. I think, the Java designers should finally take the responsibility for totally misleading thousands regarding the basic principles of error handling. They should reverse the Exception/RuntimeException relationship by making Exception extend RuntimeException, which won't break any existing code. Unintrusively advising the developer that the given method may throw a particular runtime exception should be a useful feature of your IDE - but not the compiler.
  20. Checked exceptions and contracts[ Go to top ]

    We would miss checked exceptions a lot and feel that having checked exceptions is a major plus for Java as it facilitates contract driven development.

    Following Design by Contract, a service provider may refuse a service without breaking the contract if the preconditions are not met (i.e. you don't have sufficient funds in your account). However, if all preconditions are met, service providers have to realize the service as per contract - if not there is a break of contract and hence an error.

    Within this framework, there is one checked exception per precondition and checked exceptions are only thrown if a precondition listed in the contract is not met. Otherwise there is an error (a Java RuntimeException). Checked exceptions thus enable service providers to notify clients if a requested service is refused due to a precondition not having been met.

    Having checked exceptions allows me to sleep in peace since I know, no matter which service provider you plug in, it can only refuse the service under certain preconditions which I will cater for and will only break the my business process if it has an error (throws a RuntimeException). Not having checked exceptions would make me live in constant fear since there is no longer the contract at coding level and anybody can substitute any class which may refuse providing a service for whatever reasons they see fit. Nothing would enforce that only classes which realize the contract are substituted.
  21. Need for clean layers of granularity[ Go to top ]

    Yes, Claudio

    We would also very strongly aggree with that. We follow URDAD (see for example Wikipedia), a design methodology which directly generates the different layers of granularity.

    In a nutshell, URDAD starts the design for a use case by requiring you to
      - identify the core responsibilities which need to be addressed (the respomsibilities fix the level of granularity for the current layer,
      - assigning each resopnsibility to a separate component or alternatively to an external service provider (an actor)
      - specifying how the components within the current layer of granularity collaborate to realize the use case (sequence & activity diagrams)
      - projecting out the collaboration context which is that subset of the static model (class diagrams) which at the current level of granularity, realizes the usew case.

    In URDAD one makes the transition to the next lower level of granularity by selecting one of the components from the current level of granularity as the new context. Its services at the current level of granularity become use cases at the next lower level of granularity. Picking one of these use cases, one starts the next iteration by once again identifying responsibilities and assigning them to components of the next lower level of granularity.

    In this way URDAD ensures that the resultant design exhibits a high level of cohesion (enforcing the single responsibility principle) and projects out directly the different levels of granularity.

    In addition to Wikipedia's URDAD article, there is also an article on URDAD available at www.solms.co.za -> downloads.
  22. Why Catch What you Don’t Want[ Go to top ]

    An opposite approach to not throwing checked exceptions is only catching exceptions of interest. Just because an interface throws an exception or several types of exceptions does not mean you are obligated to explicitly catch and handle every one. Simply catching Exception is sufficient in almost all cases. For example:

    public void doSomething() {
        try {
            ...
        } catch (Exception ex) {
            … handle in some general purpose fashion
        }
    }

    This approach addresses the code litter in that your code will typically only have one catch block and the catch blocks are all fairly uniform. It also addresses leaky abstraction in that there are usually no references to the API specific exceptions.

    Checked exceptions are part of the contract provided by the interface. In almost all cases the block of code calling it does not particularly care why the exception was thrown, just that an exception was thrown. However, there are still some occasions where the calling code needs to check for a specific type of exception.
  23. Proper Layering[ Go to top ]

    I believe the single biggest source of problem associated with not knowing what to do with checked exceptions is the fact that, code in many cases is not correctly layered. Following on from what Fritz has said, exceptions are an essential component for design by contract. They are there to cater for the exceptional circumstances that arise within code and hence play a vital role.

    However, I believe that people are not layering code correctly. Clear seperation of layers determins how/what one does with a given exception. Remember, exceptions are only of value within the layer they find themselves. The layer above the given layer must have an understanding of what the exception is about and use/not use it in away that is of pertinants to itself. If the error is such that, it needs to be communicated to the layers above it, it needs to translated in a manner that is of use to the layer above it.
    This translation is required since, the higher layers do not need to know about the specifics of a given layers error since they are normally working at a diffirent level of abstaction and a courser level of granularity.
  24. I think we need to distinguish between

    1) technical exception handling : this is where unckecked exceptions are superior as we can see with spring + hibernate for the reasons mentioned above. Unckecked exceptions are good for handling most of the UNEXPECDED technical problems.

    2) business exception handling : with that I mean exceptions thrown by a business service layer reporting EXPECTED situations like “InsufficientFundsException” or “ProductOutOfStockException”. These exceptions are usually discovered early during OOA and are documented in the use case model as business situations. With “excpected” I mean that the occur from time to time and must be handeled by a client application using a business service. If a product is out of stock I would like to be suggested an alternative instead of getting a message “cant perform operation”. Since these exceptions are not only expected but also required to be handeled I would always use checked exceptions and NEVER unchecked ones.