Re: Best way to halt Java process?
On 06/12/2010 09:47 PM, Lew wrote:
A "reasonable" program wouldn't be able to run properly if it didn't
have the needed classes or fields available. While that program
certainly could, and I agree should log that type of error, that's not
tantamount to recovery, only graceful exit.
I have seen a program or two that caught that error to determine the
capability of the VM, and fell back to a poorer version of the method if
the intended didn't have what it needed. Those errors in particular I
can see being caught for some sort of binary compatibility checking, but
it's definitely not recommended.
The sum list of errors:
1. AnnotationFormatError and subclasses of LinkageError: this means you
have runtime incompatibility; fixing it is generally not possible. If
you do a lot of dynamic loading, this may be worthwhile to catch.
2. AssertionError: self-explanatory.
3. AWTError, IOError: the Javadocs don't explain what causes these to be
thrown, but the implication is that recovery is not possible. These
don't seem to be used very much, and where I did find them used, it
seemed to be along the lines of "the internal file code crapped out"
4. ThreadDeath: Thread.stop was called. It's only an Error because too
many people do try { } catch (Exception e) {} (as stated in the Javadocs).
5. VirtualMachineError and friends: you're out of heap, stack, constant
heap, something failed an internal consistency check, etc. Being out of
heap memory can be dealt with, but it is difficult and fraught with
error. Out of stack is also possible (someone wrote a buggy recursive
loop), but it is of limited use to catch. Other errors probably occur
unpredictably and are impossible to recover from.
6. Most other errors: miscoded server providers. I'm not entirely sure
why these are errors, but I'm guessing its to force them to be
propagated to the top-level so that people can fix them.
Dividing into four categories:
A. Exceptions that don't want to be caught by the standard catch-all.
This doesn't mean you can't or shouldn't handle it; it just means that
either the developers want you to explicitly handle the error by itself,
or the exception really needs to propagate (ThreadDeath and arguably
AssertionError are in the latter clause).
B. "Oh crap, I just shit myself, kthxbye." Unless you're working around
a specifically documented internal bug, you probably can't work around
these reliably.
C. Binary incompatibility at runtime. Catching these is possible and
practical, if you know precisely when these errors would occur. Working
around could be providing your own alternative or failing to load an
external package without crashing the package. This could result in
later errors, so dealing with this is nontrivial and left for the most
advanced users.
D. Inconsistent system configuration exceptions. I'm guessing the
rationale is mostly as in section A: they want to make the user--or more
likely the programmer--go back and fix the configuration to be correct.
Although theoretically the purview of an Exception, the throwers are too
commonish and the errors too rarish that explicitly requiring catch
would be too burdensome. I would argue they make more sense as a
RuntimeException subclass, but apparently the developers disagreed with me.
Three of these groups have conditions where catching is feasible but it
is not generally recommended. So I guess a better wording would be:
"An error is an exception that should only be caught if the user really
knows how to work around it, so ignoring an error (as in, try { ... }
catch (Error e) {}) is not a safe operation. In general, most programs
would prefer to die over handling one of these errors."
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth