The Artima Developer Community
Sponsored Link

Weblogs Forum
What's Your ShouldNeverHappenException?

73 replies on 5 pages. Most recent reply: Jan 26, 2007 9:01 PM by Gregg Wonderly

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 73 replies on 5 pages [ « | 1 ... 2 3 4 5 ]
Morgan Conrad

Posts: 307
Nickname: miata71
Registered: Mar, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 19, 2007 12:23 PM
Reply to this message Reply
Advertisement
> "An Error is a subclass of Throwable that indicates
> serious problems that a reasonable application should
> not try to catch.
"

In my original post, I wan't catching the Error. I was letting the JVM print it to stderr and exiting. You were the one who insisted on logging it. That's a reasonable request, so I listened to you, compromised, and said, o.k., lets catch it but just to make sure it gets logged/captured correctly in your environment. No attempt at recovery.

So I listen to your concerns, compromise with you, and, in between calling me lazy, not-caring about quality, and arrogant, you throw dogma at me? (BTW, nowhere is that javadoc does it say this Error is reserved for JVM issues)



James - just what is your proposal? So far, I've heard "throw RuntimeException". If that is your literal design, IMO that's completely wrong, cause RuntimeException doesn't meet the need, with which you agree, to say "this is really really unexpected".

So I'm guessing you mean to throw a subclass, say JamesReallyBadRuntimeException. (Let's simplify to JamesRBRE). The trouble is, this is not standard. If you follow this idea, you are also going to see

JAXBRBRE
ApacheRBRE
MorganRBRE
SpringRBRE
JFreeChartRBRE
HibernateRBRE
etc ...

These are tedious to catch, and, arguably, a big waste of time and clutter cause these are only going to be thrown a handful of times, if that, over the lifetime of the product.

The big problem is that you really don't know which ones to catch - what if some library changes from JAXB to XStream for it's XML processing? And changes from Hibernate to JDO?


Error is not perfect, but its the best option proposed.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 19, 2007 5:34 PM
Reply to this message Reply
> The key issue here is what is impossible. What does
> impossible mean? What should the code assume and not try
> to handle? It depends on what scope the programmer is
> considering. The larger the scope, the more complexity
> and bugs.

I agree with this. I still think there's no good reason to throw an Error in this case but you clearly see it differently and your argument isn't unreasonable. I guess we'll just have to agree to disagree.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 19, 2007 5:59 PM
Reply to this message Reply
> > "An Error is a subclass of Throwable that indicates
> > serious problems that a reasonable application
> should
> > not try to catch.
"
>
> In my original post, I wan't catching the Error. I was
> letting the JVM print it to stderr and exiting. You were
> the one who insisted on logging it. That's a reasonable
> request, so I listened to you, compromised, and said,
> o.k., lets catch it but just to make sure it gets
> logged/captured correctly in your environment
. No
> attempt at recovery.

But what the root issue is that you are creating the Error. If you just wrapped it as an Exception, there would be no question about catching Errors.

The general rule of thumb is that programs should not try to catch Errors. You are throwing an Error. If the programmers calling your code don't catch Error (as most Java developers won't) then the it won't be caught. Did I not explain this already?

> So I listen to your concerns, compromise with you, and, in
> between calling me lazy, not-caring about quality, and
> arrogant, you throw dogma at me? (BTW, nowhere is that
> javadoc does it say this Error is reserved for JVM
> issues)

What dogma? Are you saying the documentation is dogma? Does that include any kind of technical documentation?

Not in the JavaDocs but the JLS states:

"Exceptions that are represented by the subclasses of class Error, for example OutOfMemoryError, are thrown due to a failure in or of the virtual machine."

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#41434

But if you just consider documentation like this to be dogma then it's probably not convincing.

> James - just what is your proposal? So far, I've
> heard "throw RuntimeException". If that is your literal
> design, IMO that's completely wrong, cause
> RuntimeException doesn't meet the need, with which you
> agree, to say "this is really really unexpected".

I don't think it's important to communication how unexpected it was. Unless I'm going to do something different, what purpose does it serve?

> So I'm guessing you mean to throw a subclass,

Bad guess. I don't see much value in creating an Exception class if it doesn't have any special behavior and I'm not going to do anything different when it's thrown. I can't see why I would need special code for something that is extremely unlikely to occur. It would just fall into the 'something happened that prevents this operation' category. It's not like a DB connection failure where you might want to put up a message saying "try again later". This is one of those 'contact support' kinds of errors.

> These are tedious to catch, and, arguably, a big waste of
> time and clutter cause these are only going to be thrown a
> handful of times, if that, over the lifetime of the
> product.

Even if I did create a sublclass of RuntimeException, I would still just catch Exception at the fault barrier. I'm not sure where you have gotten these ideas. Is that the kind of error handling you work with?

Nuwan Goonasekera

Posts: 32
Nickname: nuwang
Registered: Apr, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 19, 2007 10:16 PM
Reply to this message Reply
Thought of pitching in. I wonder whether this issue can be discussed further based on a contrived example. Let's imagine writing a media player app or something which supports plugins. The program attempts to load the plugin, but if the plugin fails, we don't really care, and simply output a message indicating that the plugin suffered a fatal error. A snippet would look something like this.
   protected void createPlugin(String pluginName)
   {
       Plugin somePlugin = PluginFactory.createPlugin(pluginName);
       try
       {
          somePlugin.execute();
       }
       catch (Exception oops)
       {
          // Alert user about plugin error
       }
   }


Now, the plugin can throw exceptions for a variety of reasons. But one assumption: under no circumstance do we want to catch an Error, since this would indicate a system-wide failure where further execution is impossible. So some of the exceptions the plugin might throw:

1. A run-of-the-mill exception
We simply alert the user.

2. A serious VM Error
We really don't want to catch Error here because we can't reasonably expect to continue anyway.

3. An assertion failure (on the part of the plugin)
That would signal some serious condition. The question is, does a failure in an invariant of the plugin translate into a system wide failure? Perhaps the rest of the system can continue executing? For example, let's say the plugin encounters an unsupported encoding exception for UTF-8 and decides to throw an AssertionError. Now, while this may indicate a broken JVM, I would not expect the plugin developer to make that decision for me - it might still be possible for the rest of the application to continue executing.

On the other hand, if the JVM is completely under your control, and an assertion error on your part is indeed a system-wide failure then I guess it might be ok to fail so hard and so fast that the JVM itself exits. It would appear to depend on whether your app is something like a bean, hosted within an application server or a standalone app. completely under your control. (Which also bring me to the question, what does an App Server do if a bean throws an Error?)

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 7:20 AM
Reply to this message Reply
> 3. An assertion failure (on the part of the plugin)
> That would signal some serious condition. The question is,
> does a failure in an invariant of the plugin translate
> into a system wide failure? Perhaps the rest of the system
> can continue executing? For example, let's say the plugin
> encounters an unsupported encoding exception for UTF-8 and
> decides to throw an AssertionError. Now, while this may
> indicate a broken JVM, I would not expect the plugin
> developer to make that decision for me - it might still be
> possible for the rest of the application to continue
> executing.

Very well written post. Thanks. I would think that if a system supporting plugins was meant to run with assertions turned on, it would have to catch AssertionErrors from plugins. I don't know why it was decided to use Errors for assertion failures. My best guess is that they were designed with the assumption that they would be turned off after testing (also evidenced by the fact that they are turned off by default.)

> On the other hand, if the JVM is completely under your
> control, and an assertion error on your part is indeed a
> system-wide failure then I guess it might be ok to fail so
> hard and so fast that the JVM itself exits. It would
> appear to depend on whether your app is something like a
> bean, hosted within an application server or a standalone
> app. completely under your control. (Which also bring me
> to the question, what does an App Server do if a bean
> throws an Error?)

I know that some Errors are cannot be recovered from reliably such as OutOfMemoryError on any normal JVM and it will crash the app-servers I have worked with. I've worked with an AppServer-esque tool that did apparently not shutdown on OutOfMemoryErrors and the whole server would start malfunctioning after that occurred. It would just dump a stack trace to a log and you'd only know something was wrong because it would stop doing anything productive. It was a memory hog with space leaks so it would happen relatively frequently.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 7:35 AM
Reply to this message Reply
The assertion usage guide appears to back-up the idea that AssertionErrors were never intended for proving correctness in production code:

"There are also a few situations where you should not use them:

* Do not use assertions for argument checking in public methods.

Argument checking is typically part of the published specifications (or contract) of a method, and these specifications must be obeyed whether assertions are enabled or disabled. Another problem with using assertions for argument checking is that erroneous arguments should result in an appropriate runtime exception (such as IllegalArgumentException, IndexOutOfBoundsException, or NullPointerException). An assertion failure will not throw an appropriate exception."

Apparently there are quite a few people using for these purposes. You can make an argument that the recommendations are wrong but it remains that this was not the intended purpose.

Jay Sachs

Posts: 30
Nickname: jaysachs
Registered: Jul, 2005

ShouldNeverHappenException -> smelly API Posted: Jan 20, 2007 9:51 AM
Reply to this message Reply
It seems to me that when I'm forced to deal with an exception that really should never happen, the API is poorly designed. Bill's example is one of my favorite ones to hate, the UnsupportedOperationException when supplying "UTF-8", which is guaranteed to be supported. The fact that Java's character {en|de}coding isn't based on a CharacterEncoding class (or enum) is pretty unforgivable to me. It would be pretty straightforward to offer overloaded methods wherever the String encoding is accepted.

Back to the topic, I'd say my preferred ShouldNeverHappenException is either FindOrWriteAnotherAPIException or UseADifferentLanguageException.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 10:22 AM
Reply to this message Reply
> "There are also a few situations where you should not use
> them:
>
> * Do not use assertions for argument checking in
> g in public methods.
>
> Argument checking is typically part of the published
> lished specifications (or contract) of a method, and these
> specifications must be obeyed whether assertions are
> enabled or disabled. Another problem with using assertions
> for argument checking is that erroneous arguments should
> result in an appropriate runtime exception (such as
> IllegalArgumentException, IndexOutOfBoundsException, or
> NullPointerException). An assertion failure will not throw
> an appropriate exception."

Forgot to put the link for the above:

http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html

Nuwan Goonasekera

Posts: 32
Nickname: nuwang
Registered: Apr, 2006

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 12:43 PM
Reply to this message Reply
The link has some interesting info about using static intializers to ensure assertions are turned on in production environments. All in all though, it is clearly stated that asserts may even be stripped off by the compiler, making their runtime usage somewhat problematic.

And thanks for posting that link to Barry Ruzek's article. Really put a lot of things into perspective for me. I always did like the fact that checked exceptions made the compiler alert me to different outcomes of a method call - but with all the complaints about certain APIs, I had almost started to think that checked exceptions were pretty evil :)

Jay Sachs

Posts: 30
Nickname: jaysachs
Registered: Jul, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 1:23 PM
Reply to this message Reply
> The assertion usage guide appears to back-up the idea that
> AssertionErrors were never intended for proving
> correctness in production code

I never use Java built-in assertions, based on the reading of the guide. In fact, the guidelines lead me to the conclusion that the 'assert' statement has little, if any, use at all.

What are the classes of invariants one would like checked during "testing" or "development" but not "production"?
"Costly" invariants? To me, that's of limited value, and hardly worth a new keyword.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 5:20 PM
Reply to this message Reply
> I never use Java built-in assertions, based on the reading
> of the guide. In fact, the guidelines lead me to the
> conclusion that the 'assert' statement has little, if any,
> use at all.

I don't use them either. I can only see using them for checking for internal errors in classes. Like, a private methods argument(s) are never null. Of course, in most cases, you'd end up with a NullPointerException in testing at some point anyway.

> What are the classes of invariants one would like checked
> during "testing" or "development" but not "production"?
> "Costly" invariants? To me, that's of limited value, and
> hardly worth a new keyword.

I don't see it as being much different from having unit tests for every class. I think unit tests make sense for classes that don't depend on external state but for anything else, I prefer regression testing. In other words, tests that are representative of how the code is used (as a whole) in production.

An interesting parallel was in an article I read in an engineering magazine. The article was about how Toyota and Honda have achieved such high levels of reliability. In a nutshell the point of the article was that there is a commonly held understanding that Toyota and Honda do this with high-precision parts. This is actually false. The precision of a Honda or Toyota part is (on average) less than that of the German or American car manufacturers. But the overall precision of the final product is greater. In other words the assumption that lots of precise parts add up to a precise product is wrong and that how everything fits together is more important.

To bring this back to software, I see unit testing and the use of assertions as a testing tool to be a myopic way of judging software quality. Who cares if assertion X fails if it has no impact of the overall functioning of the software? just because class A's unit tests all succeed and class B's unit tests all succeed doesn't tell you anything about how they will work together.

So anyway, I agree, assertions as intended to be used in Java are pretty much worthless. If they were a more concise way to throw Exceptions on bad conditions, I might see it differently.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 20, 2007 5:27 PM
Reply to this message Reply
> The link has some interesting info about using static
> intializers to ensure assertions are turned on in
> production environments. All in all though, it is clearly
> stated that asserts may even be stripped off by the
> compiler, making their runtime usage somewhat
> problematic.

I does say something about how assertions are evaluated before the class is initialized even if they are turned off. So I can see that as a useful tool for preventing a class from loading if everything is all wrong.

> And thanks for posting that link to Barry Ruzek's article.
> Really put a lot of things into perspective for me. I
> always did like the fact that checked exceptions made the
> compiler alert me to different outcomes of a method call -
> but with all the complaints about certain APIs, I had
> almost started to think that checked exceptions were
> pretty evil :)

I don't disagree with anything in that article (unless I missed something) and that's rare, given what a disagreeable bastard I am. It really describes pretty much what I have come to do anyway. What I really like is that he introduces the terminology of fault vs. contingency and the term 'fault-barrier' which I believe to be the key to good a robust, fault-tolerant (no pun intended) Java application.

Gregor Zeitlinger

Posts: 108
Nickname: gregor
Registered: Aug, 2005

Re: What's Your ShouldNeverHappenException? Posted: Jan 21, 2007 4:16 AM
Reply to this message Reply
> I don't think it's important to communication how
> unexpected it was. Unless I'm going to do something
> different, what purpose does it serve?
Yes, that exactely the point.
You can either recover from that error and other programming errors in general or you can't. It's hilarious to think that you cannot recover from the missing UTF-8, but from a NullPointerException (I think James already said this).

In contrast, there is no sensible strategy to recover from OutOfMemoryException or StackOverflowException (maybe if you start jobs in separate JVMs - but in that case, you can indeed recover from a JVM exit).

Gregg Wonderly

Posts: 317
Nickname: greggwon
Registered: Apr, 2003

Re: What's Your ShouldNeverHappenException? Posted: Jan 26, 2007 9:01 PM
Reply to this message Reply
> > I don't think it's important to communication how
> > unexpected it was. Unless I'm going to do something
> > different, what purpose does it serve?
> Yes, that exactely the point.
> You can either recover from that error and other
> programming errors in general or you can't. It's hilarious
> to think that you cannot recover from the missing UTF-8,
> but from a NullPointerException (I think James already
> said this).

One thing that I always consider is whether the leg of code that such an exception might surface in is an important thread, or not. Many times, it helps to let the logic fail and try again so that you see the error, but can use other logic in the application to deal with it externally, such as disabling an optional part of the app which shouldn't be on, and is thus throwing rolling exceptions like this exception would.

> In contrast, there is no sensible strategy to recover from
> OutOfMemoryException or StackOverflowException (maybe if
> you start jobs in separate JVMs - but in that case, you
> can indeed recover from a JVM exit).

I always start my JVMs is scripts on UN*X which have an embedded loop to restart the JVM should it exit. You could also run it under init(3), or perhaps a windows service etc. and configure it for restart.

Flat View: This topic has 73 replies on 5 pages [ « | 2  3  4  5 ]
Topic: What's Your ShouldNeverHappenException? Previous Topic   Next Topic Topic: C++ Delegation and Dynamic Inheritance

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use