Thread.UncaughtExceptionHandler
states that when the method which handles uncaught exceptions itself throws an exception, that exception will be ignored:
void uncaughtException(Thread t, Throwable e):
Method invoked when the given thread terminates due to the given uncaught exception.
Any exception thrown by this method will be ignored by the Java Virtual Machine.
However when I tested it, the JVM did not ignore the exceptions handled by the uncaught exception handler`:
public static void main(final String args[]) {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread arg0, Throwable arg1) {
throw new java.lang.RuntimeException("e2");
}
});
throw new RuntimeException("e1");
}
Eclipse Console output (JRE 1.7):
Exception: java.lang.RuntimeException thrown from the UncaughtExceptionHandler in thread "main"
Another oddity I found out is that the output I get isn't coming from System.err
. It seems to be from another stream altogether. I verified this by redirecting System.err
to System.out
, but I'm still getting "red" output:
public static void main(final String[] args) {
System.setErr(System.out);
System.out.println(System.err == System.out);
System.err.println("this is black color");
try {
throw new Error("test stacktrace color");
} catch (Throwable e) {
e.printStackTrace();
}
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
throw new RuntimeException("from handler");
}
});
throw new RuntimeException("from main");
}
The output (bolded signifies red color):
true
this is black color
java.lang.Error: test stacktrace color at asf.df.main(df.java:13)
Exception: java.lang.RuntimeException thrown from the UncaughtExceptionHandler in thread "main"
What's the explanation for these phenomenons?
What happens to errors thrown within UncaughtExceptionHandler? What's the expected (documented or guaranteed) behavior?
The exceptions are ignored and processing continues when thrown from a non-main thread.
If it is thrown in main the error code returned is non-zero.
The unhandled exceptions are logged via syserr.
Output:
In child UncaughtExceptionHandler at 2014-07-19T04:10:46.184Z
Exception: java.lang.RuntimeException thrown from the UncaughtExceptionHandler in thread "Thread-0" After child thread: 2014-07-19T04:10:48.197Z In main UncaughtExceptionHandler 2014-07-19T04:10:48.197Z
Exception: java.lang.RuntimeException thrown from the UncaughtExceptionHandler in thread "main"
HotSpot JVM prints the exceptions thrown from the UncaughtExceptionHandler. See JavaThread::exit
JVM prints these exceptions itself directly on
stderr
regardless of theSystem.err
state - whether it was redirected or not.Well, this kind of warning does not affect the application - in this sense the exception is "ignored". But you are right, this behavior is not obvious. Javadoc is misleading and is better to be fixed.