RuntimeException
is thrown, but is not handled by your program?
In the simplest Java programs run from the console and executed in a single thread, the default behavior is to:
There are two common kinds of programs where the above behavior is not in effect:
In Swing applications, the default behavior still prints the stack trace to the console, but the Event Dispatch Thread (the main Swing thread) is not terminated.
The Event Dispatch Thread always remains alive, in spite of any RuntimeException
s thrown by your program.
However, simply printing a stack trace to the console in a Swing application is not very informative for the average user. Instead, you should likely override Java's default handling of uncaught exceptions. The benefits are:
If you're using JDK 5+, then you may define your own
UncaughtExceptionHandler
.
They can be defined at 3 different levels.
From the highest level to the lowest level, they are:
Thread.setDefaultUncaughtExceptionHandler
upon startup
ThreadGroup.uncaughtException
Thread.setUncaughtExceptionHandler
Example
Here's an example of such a handler class.
package hirondelle.movies.exception; import hirondelle.movies.util.Util; import hirondelle.movies.util.ui.UiUtil; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.util.logging.Logger; import javax.swing.JOptionPane; /** Custom handler for any uncaught exceptions. <P>By default, a Swing app will handle uncaught exceptions simply by printing a stack trace to {@link System#err}. However, the end user will not usually see that, and if they do, they will not likely understand it. This class addresses that problem, by showing the end user a simple error message in a modal dialog. (The dialog's owner is the currently active frame.) */ public final class ExceptionHandler implements Thread.UncaughtExceptionHandler { /** Custom handler for uncaught exceptions. <P>Displays a simple model dialog to the user, showing that an error has occured. The text of the error includes {@link Throwable#toString()}. The stack trace is logged at a SEVERE level. */ @Override public void uncaughtException(Thread aThread, Throwable aThrowable) { fLogger.severe(getStackTrace(aThrowable)); JOptionPane.showMessageDialog( UiUtil.getActiveFrame(), "Error: " + aThrowable.toString(), "Error", JOptionPane.ERROR_MESSAGE ); } // PRIVATE private static final Logger fLogger = Util.getLogger(ExceptionHandler.class); private String getStackTrace(Throwable aThrowable) { final Writer result = new StringWriter(); final PrintWriter printWriter = new PrintWriter(result); aThrowable.printStackTrace(printWriter); return result.toString(); } }
For JDK 1.4, the simplest way of overriding the default handler for uncaught exceptions is to use the following undocumented feature (which has actually been removed from JDK 7):
public void handle(Throwable aThrowable){...}
System
property named 'sun.awt.exception.handler'
, whose value is
the fully qualified class name of this new handler class