Java Asynchronous Exceptions: Can I catch them? - java

I have been reading the JLS and I encountered the section 11.1.3. Asynchronous Exceptions from which I quote:
Most exceptions occur synchronously as a result of an action by the
thread in which they occur, and at a point in the program that is
specified to possibly result in such an exception. An asynchronous
exception is, by contrast, an exception that can potentially occur at
any point in the execution of a program.
And
Asynchronous exceptions occur only as a result of:
[...]
An internal error or resource limitation in the Java virtual machine that prevents it from implementing the semantics of the
Java programming language. In this case, the asynchronous exception
that is thrown is an instance of a subclass of VirtualMachineError.
Is it possible to catch such exceptions for logging purposes or notification (because I believe such thing is unrecoverable)? How can I achieve such thing?

You can catch such exceptions just like any other exception. The only problem is that they may occur at any place in your program, so catching them reliably is hard. You would basically have to wrap the run method of all threads and the main method in a try..catch block, but you can't do that for threads you don't control (like the Swing EDT, or threads for timers etc.).
Also catching any subclass of Error is usually not recommended, because the JVM may be in an unstable state, which might lead to a further failure (for example in the case of OutOfMemoryError, you might not even have enough memory to to the exception handling). However, logging would be a valid reason for catching Errors in my eyes.
My suggested solution would be to use an uncaught exception handler for this by setting it as the default exception handler. In this handler you will get all exceptions and errors, if they are not caught anywhere in the code, and you can try to log them.

There is no point of catching these exceptions (Subclasses of VirtualMachineError) as you have no indecattion in which state the pogram is at the point, the Doc saies about Virtual Machine Errors:
A Java virtual machine implementation throws an object that is an
instance of a subclass of the class VirtualMethodError when an
internal error or resource limitation prevents it from implementing
the semantics described in this chapter. This specification cannot
predict where internal errors or resource limitations may be
encountered and does not mandate precisely when they can be reported.
so assuming you get in an OutOfMemoryError or an UnknownError there isnt much you can do about it, and once your vritualmashine doesnt work properly you cant provide the user anyhelp as your program isnt working properly as well, besides you have no idea at what time, point, and reason it happends since its not a code error that was caused from your program.

Related

Is catching Throwable in schedulers a good practice?

I rather say that fail fast and not catching Throwable is a good practice. But in case unhandled exception in request processor like StackOverflowError, the task may be stopped. And that doesn't always sound good. I'd rather catch StackOverflowError over and over, but some tasks might be processed. What is good practice here?
There is no "good practice" or "best practice"1 about catching Error and hence Throwable.
On the one hand, a JVM can recover successfully from some kinds of Error in some circumstances. For example, if you are running "task" on a single thread that doesn't interact with other threads (directly or indirectly), then that thread can safely recover from a StackOverflowError and possibly2 a OutOfMemoryError.
On the other hand, many Error subclasses indicate that the application or JVM is in a state where recovery is not possible, or not practical:
A class loading or initialization Error means that certain classes will be an unusable state. An application that depends the class won't be able to proceed.
If an application that uses notify / wait or higher level synchronization constructs gets (say) an OutOfMemoryError error on one thread, it is liable to leave other threads waiting for notifications, etc that may never arrive.
My recommendation would be to heed the implied advice in the javadoc for Error and not to catch and attempt recover from Error or its subclasses. If you attempt to recover, allow for the possibility that the application may "wedge".
1 - Actually, there is not "best practice" at all; see https://www.satisfice.com/blog/archives/5164
2 - This depends on the root cause. If the root cause is a memory leak elsewhere in your codebase, then recovery is a bad idea. The OOME is likely to recur ... with increasing frequency.
This is from the javadoc of Error :
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.
I usually follow this rule to avoid suppressing real unexpected errors that should be fixed.
You mentionned StackoverflowError, if you have this kind of error, there's probably a problem with your algorithm and your code should be optimized.
If you know that a specific error is likely to be thrown and you're okay with that, you can catch it.
However if you don't expect it, it's better to raise the alarm ASAP and deal with it.
Good practice is catch scheduled jobs, write log about exception, metrics and(optional) reschedule it.
Also, sometimes your thread will be stoped/destroyed (hello spring schedulers) cause you receive some sort of exception, that not critical to your job...

When would we directly extend java.lang.Error?

In what use case would a custom Error class be required?
I know there are many specialised subclasses of Error in Java API (e.g. LinkageError, ServiceConfigurationError, ThreadDeath, VirtualMachineError) but I think these are only required by the Java runtime and mostly are not required in the application code of a Java developer.
I am well aware about creating custom Exception classes and their usage scenarios, but I'm not sure about Error.
As the documentation describes:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.
Exceptions, on the other hand, are designed to be caught. Unchecked RuntimeExceptions should be caught judiciously (because the code that raised it is indicating something unexpected happened) but the JVM itself is in no danger; if the caller believes it can recover from the RuntimeException, it's safe to do so.
Therefore if there is something in your program that no "reasonable application" would ever want to handle, an Error is appropriate. This is very, very rare however.
Look at some of the existing subclasses, like LinkageError and VirtualMachineError and it's subclasses InternalError, OutOfMemoryError, StackOverflowError, and UnknownError - these are raised when the JVM has failed and there's nothing it can do to recover, not even let the user try to handle it.
If you have an additional case where your code could fail catastrophically and you want to similarly force the application to terminate, use an Error (probably an AssertionError). The vast majority of the time, however, a RuntimeException of some sort is sufficient, as it allows a user to at least try to correct the problem while the program is running.

Java: Call method on all caught exceptions [duplicate]

This question already has answers here:
Java: Global Exception Handler
(6 answers)
Closed 8 years ago.
I know I can set my own UncaughtExceptionHandler to execute code on uncaught exceptions, but is there a way to have some code execute on all caught exception without having to call that method in every single try-catch block?
My custom code sends me an email with the stack trace on uncaught exceptions. I also want that email for caught exception but I don't want to track down every single try-catch statement and add it.
I'm not looking for a global exception handler (I mentioned UncaughtExceptionHandler), I'm looking for a global CAUGHT exception handler.
You can do it by altering the Exception class to record every Exception. This can be done by changing the boot class path, runtime code injection or using the JVMTI.
I suspect it's a bad idea as the system will catch more exception than you might expect. You could get thousands of emails a second if something goes wrong.
I suggest you revisit your exceptions handling policy and strategy. When an exception happens it generally means something went wrong, i.e., something exceptional (as in unexpected) happened in the code (database connection lost, file not found, network unreachable, etc.) or a bug in the code causes an unexpected problem (NPE comes to mind...). In these scenarios the normal program flow can't continue.
It's usually considered best practice to fail fast in such cases, unless you are expecting some exception to be thrown and know how to recover, i.e., the exceptional condition wasn't that exceptional after all.
If you need to fail fast, you don't need to explicitly handle the exceptions as your thread or program will just die and you can just use the UncaughtExceptionHandler to log the stack trace, send emails or notifications etc.
Situation in which you can successfully recover and resume the normal program flow are far less common in my opinion and usually do not require developers/ops to be notified as it is part of the normal functioning of the system (otherwise you would not be able to handle the exception). So simply logging the specific message and useful data associated to this scenario is usually enough, e.g., "WARNING: Transient error x was recovered. State was y and z.".

Why does Java have both checked and unchecked exceptions? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
When to choose checked and unchecked exceptions
Why does Java as a language have both checked and unchecked exceptions. What purpose do they serve?
Note: I'm not asking when I should use them, or how to code them, but what they add to the language.
The theory for checked exceptions is simple.
When designing an interface, think of exceptional cases that can occur, and will occur, with the normal state of a method call. Declare these exceptions in your interface, as the programmer will have to handle them directly.
For example, a bank account withdraw method may declare an OverdraftException, which is an expected exception - a withdrawal may fail due to overdraft, but this type of failure may be handled differently by the client code (one may decide to completely deny the withdrawal, another may decide to apply a huge penalty and allow for a negative balance to be recorded, another may decide that their client is allowed to draw from a different account).
However, runtime exceptions were supposed to be programming errors that weren't supposed to be handled directly - such as NullPointerExceptions, which only occur if methods take invalid arguments or don't check for such cases directly.
This is a good theory. However, Java messed up with its implementation of Exceptions, and this threw the book of this theory out the window.
There are two cases that I will illustrate where Java messed up with its implementation of Exceptions. These are IOException and SQLException.
An IOException occurs anytime, anywhere a stream in the IO libraries of Java messes up. This is a checked exception, however. But, generally you cannot do anything but log that an error occur - if you're simply writing to the console, what can you reasonably be expected to do if you suddenly get an IOException when you're writing to it?
But there's more.
IOException also hides stuff like file exceptions and network exceptions. They may be subclasses of IOException floating around for that, but it is still a checked exception. If your writing to an external file fails, you can't really do much about it - if your network connection is severed, ditto.
SQLException is the same way. Exception names should show what happened when they are called. SQLException does not. SQLException is thrown any single time any possible number of errors are encountered when dealing with a database - MOST OF WHICH THAT HAVE NOTHING TO DO WITH SQL.
Therefore, programmers typically get annoyed with handling exceptions, and let Eclipse (or whatever IDE they're using) generate blocks like this:
try {
thisMethodThrowsACheckedExceptionButIDontCare();
}
catch(Exception e) {
e.printStackTrace();
}
However, with RuntimeExceptions, these intentionally bubble up and eventually get handled by the JVM or container level. This is a good thing - it forces errors to show up and then you must fix the code directly instead of ignoring the exception - you may still end up just printing the stack trace (hopefully logging it instead of printing to the console directly), but then there will be an exception handler that you were forced to write because of a real problem - not because a method said that it might possibly throw an Exception, but that it did.
Spring uses a DataAccessException to wrap SQLExceptions so that you don't have to handle them as a checked exception. It makes code much cleaner as a result - if you expect a DataAccessException, you can handle it - but most of the time you let it propagate and be logged as an error, because your SQL should be debugged by the time you release your application, meaning the DataAccessException is probably a hardware issue that you could not resolve - DataAccessException is a much more meaningful name than SQLException, because it shows that access to data failed - not that your SQL query was nessecarily at fault.
They add a differentiation between errors that the designer of a library feels must be caught, and ones that they feel the programmer shouldn't handle.
For example it might be reasonable for a program to handle bad input from a user, but if something goes wrong with the underlying OS and threads starts to die without reason, it isn't something that the program should be expected to handle.
Personally, I think checked exceptions were a mistake in Java.
That aside, designating both checked and unchecked exceptions allows a library to differentiate between recoverable and unrecoverable errors. By making all recoverable errors throw checked exceptions, a library/language can force a developer to handle the edge cases they might otherwise paper over.
The big problem with this:
try{
myCode();
}catch(Exception e){ //Do nothing }
Additionally, in most cases it really is best to just throw up your hands and pass an exception up when one occurs. By forcing checked exceptions to be declared, a method that really doesn't care if an error occurs ends up having dependencies (in terms of compatibility, but also code-smell and others) it really shouldn't.
I think Sun initially thought it would be a good idea because the programmer is forced to handle the exception. However, many years later, pretty much everyone agrees they are a bad, unneccessary addition.
One of the main issues (apart from cluttering code) is that they leak abstractions form lower layers to higher layers (such as rmi remote exceptions)
Checked and unchecked exceptions invokes a bit of a religious argument - Java fell one side of the fence, C# the other.
In Java checked exceptions should be used when the calling code can recover from the error as where unchecked exceptions are used when there's a critical error (with perhaps the exception - no pun intended - of NullPointerException) that the calling code is unlikely to be able to recover from.
Personally I like to have both available to me generally favouring checked exceptions because they allow me to force the calling code to deal with an error situation that a developer might otherwise have ignored (although the infamous empty catch block side-steps this).
I don't think there's anything at all conceptually wrong with checked exceptions... but they do tend to suck mightilly in practice, because (especially early) library developers over-use them.
Also the "catch or declare" requirement does NOT fit well with interfaces.
My basics thoughts are: "Stuff that goes wrong" comes in two basic flavours: recoverable, and unrecoverable... Ergo: Business Exceptions and System Errors.
For instance: What do you (the library developer) expect me (the application programmer) to do about recovering from a failure in a call to SomeStream.close()? Yes, I definately need to be made aware that something has gone horribly wrong, but really my only option is to terminate the program/request/process/thread which tripped over it. I cannot be reasonably expected to even attempt to recover from the situation... Ergo: It's an uncoverable error, and therefore I shouldn't be forced to write a lot of highly repitious boilerplate catch-blocks which don't handle the problem at every level of the (potentially very deep) callstack. Therefore I believe it would be better if "catch all" checked exceptions such as IOException had never been invented... CloseException extends UncheckedIOException would be more appropriate, IMHO.
Also, if I had a time machine I'd go back in time and plead with the Java gods for:
interface Throwable
abstract class Exception
abstract class CheckedException
abstract class UncheckedException
class Error
Also: I'd love to see a #FaultBarrier class-annotation, which makes the compiler enforce: All exceptions (especially unchecked ones) must be caught or explicitly thrown. The most horribilest hunk of system I've ever worked on was riddled with throwings of raw RuntimeException; It's enough to make you weep.
Cheers. Keith.

When to catch java.lang.Error?

In what situations should one catch java.lang.Error on an application?
Generally, never.
However, sometimes you need to catch specific errors.
If you're writing framework-ish code (loading 3rd party classes), it might be wise to catch LinkageError (no class def found, unsatisfied link, incompatible class change).
I've also seen some stupid 3rd-party code throwing subclasses of Error, so you'll have to handle those as well.
By the way, I'm not sure it isn't possible to recover from OutOfMemoryError.
Never. You can never be sure that the application is able to execute the next line of code. If you get an OutOfMemoryError, you have no guarantee that you will be able to do anything reliably. Catch RuntimeException and checked Exceptions, but never Errors.
http://pmd.sourceforge.net/rules/strictexception.html
In multithreaded environment, you most often want to catch it! When you catch it, log it, and terminate whole application! If you don't do that, some thread that might be doing some crucial part would be dead, and rest of the application will think that everything is normal. Out of that, many unwanted situations can happen.
One smallest problem is that you wouldn't be able to easily find root of the problem, if other threads start throwing some exceptions because of one thread not working.
For example, usually loop should be:
try {
while (shouldRun()) {
doSomething();
}
}
catch (Throwable t) {
log(t);
stop();
System.exit(1);
}
Even in some cases, you would want to handle different Errors differently, for example, on OutOfMemoryError you would be able to close application regularly (even maybe free some memory, and continue), on some others, there is not much you can do.
Generally you should always catch java.lang.Error and write it to a log or display it to the user. I work in support and see daily that programmers cannot tell what has happened in a program.
If you have a daemon thread then you must prevent it being terminated. In other cases your application will work correctly.
You should only catch java.lang.Error at the highest level.
If you look at the list of errors you will see that most can be handled. For example a ZipError occurs on reading corrupt zip files.
The most common errors are OutOfMemoryError and NoClassDefFoundError, which are both in most cases runtime problems.
For example:
int length = Integer.parseInt(xyz);
byte[] buffer = new byte[length];
can produce an OutOfMemoryError but it is a runtime problem and no reason to terminate your program.
NoClassDefFoundError occur mostly if a library is not present or if you work with another Java version. If it is an optional part of your program then you should not terminate your program.
I can give many more examples of why it is a good idea to catch Throwable at the top level and produce a helpful error message.
Very rarely.
I'd say only at the top level of a thread in order to ATTEMPT to issue a message with the reason for a thread dying.
If you are in a framework that does this sort of thing for you, leave it to the framework.
Almost never. Errors are designed to be issues that applications generally can't do anything about. The only exception might be to handle the presentation of the error but even that might not go as planned depending on the error.
An Error usually shouldn't be caught, as it indicates an abnormal condition that should never occur.
From the Java API Specification for the Error class:
An Error is a subclass of Throwable
that indicates serious problems that a
reasonable application should not try
to catch. Most such errors are
abnormal conditions. [...]
A method is not required to declare in
its throws clause any subclasses of
Error that might be thrown during the
execution of the method but not
caught, since these errors are
abnormal conditions that should never
occur.
As the specification mentions, an Error is only thrown in circumstances that are
Chances are, when an Error occurs, there is very little the application can do, and in some circumstances, the Java Virtual Machine itself may be in an unstable state (such as VirtualMachineError)
Although an Error is a subclass of Throwable which means that it can be caught by a try-catch clause, but it probably isn't really needed, as the application will be in an abnormal state when an Error is thrown by the JVM.
There's also a short section on this topic in Section 11.5 The Exception Hierarchy of the Java Language Specification, 2nd Edition.
If you are crazy enough to be creating a new unit test framework, your test runner will probably need to catch java.lang.AssertionError thrown by any test cases.
Otherwise, see other answers.
And there are a couple of other cases where if you catch an Error, you have to rethrow it. For example ThreadDeath should never be caught, it can cause big problem is you catch it in a contained environment (eg. an application server) :
An application should catch instances of this class only if it must clean up
after being terminated asynchronously. If ThreadDeath is caught by a method,
it is important that it be rethrown so that the thread actually dies.
Very, very rarely.
I did it only for one very very specific known cases.
For example, java.lang.UnsatisfiedLinkError could be throw if two independence ClassLoader load same DLL. (I agree that I should move the JAR to a shared classloader)
But most common case is that you needed logging in order to know what happened when user come to complain. You want a message or a popup to user, rather then silently dead.
Even programmer in C/C++, they pop an error and tell something people don't understand before it exit (e.g. memory failure).
In an Android application I am catching a java.lang.VerifyError. A library that I am using won't work in devices with an old version of the OS and the library code will throw such an error. I could of course avoid the error by checking the version of OS at runtime, but:
The oldest supported SDK may change in future for the specific library
The try-catch error block is part of a bigger falling back mechanism. Some specific devices, although they are supposed to support the library, throw exceptions. I catch VerifyError and all Exceptions to use a fall back solution.
it's quite handy to catch java.lang.AssertionError in a test environment...
Ideally we should not handle/catch errors. But there may be cases where we need to do, based on requirement of framework or application. Say i have a XML Parser daemon which implements DOM Parser which consumes more Memory. If there is a requirement like Parser thread should not be died when it gets OutOfMemoryError, instead it should handle it and send a message/mail to administrator of application/framework.
ideally we should never catch Error in our Java application as it is an abnormal condition. The application would be in abnormal state and could result in carshing or giving some seriously wrong result.
It might be appropriate to catch error within unit tests that check an assertion is made. If someone disables assertions or otherwise deletes the assertion you would want to know
There is an Error when the JVM is no more working as expected, or is on the verge to. If you catch an error, there is no guarantee that the catch block will run, and even less that it will run till the end.
It will also depend on the running computer, the current memory state, so there is no way to test, try and do your best. You will only have an hasardous result.
You will also downgrade the readability of your code.

Categories