One More Note on Uncaught Exception Handlers

When I wrote about uncaught exception handlers on Oct 7, I omitted one important detail. If your Swing app throws an exception while displaying a modal dialog, uncaught exception handlers are not invoked.

Instead, Swing simply prints the stack trace to the console. This is troublesome in many GUI apps because your customers may not have a “console” to see these stack traces. From their perspective, absolutely nothing happens, other than your app becomes unresponsive.

Here is the reason: Swing cannot propagate an exception from the EventDispatchThread when a modal dialog is active. This would interrupt the very loop that makes the dialog modal in the first place. Here is a snippet of code from EventDispatchThread:

private void processException(Throwable e, boolean isModal) {
  if (!handleException(e)) {
    // See bug ID 4499199.
    // If we are in a modal dialog, we cannot throw
    // an exception for the ThreadGroup to handle (as added
    // in RFE 4063022).  If we did, the message pump of
    // the modal dialog would be interrupted.
    // We instead choose to handle the exception ourselves.
    // It may be useful to add either a runtime flag or API
    // later if someone would like to instead dispose the
    // dialog and allow the thread group to handle it.
    if (isModal) {
      System.err.println(
        "Exception occurred during event dispatching:");
      e.printStackTrace();
    } else if (e instanceof RuntimeException) {
      throw (RuntimeException)e;
    } else if (e instanceof Error) {
      throw (Error)e;
    }
  }
}

So how can we intercept these exceptions and show an error dialog to the user?

The secret lies in the handleException(…) method. This method looks for the existence of a system property sun.awt.exception.handler. The comments for handleException(…) define the exact requirements, but briefly:

  • The property value is a class name
  • Swing uses reflection to load the class and invoke its public no-arg constructor
  • Again, using reflection, Swing invokes the handle(Throwable t) method

Note that the comments also make it clear this property WILL GO AWAY at some point. For now, it works. Be aware that when Java 7, or 8, or 9 comes out, code relying on this implementation detail will eventually fail.

Here is how you write a Swing exception handler:

public static class AwtHandler {
  public void handle(Throwable t) {
    // do something here
  }
}

I does not have to be static…I just pasted in a snipped from my code, which happens to be static. And here is how you register your handler:

System.setProperty("sun.awt.exception.handler", AwtHandler.class.getName());

Where the comment says “do something here”, I recommend you simply delegate to your normal uncaught exception handler that I blogged about here.


One Response to “One More Note on Uncaught Exception Handlers”

[...] See One More Note on Uncaught Exception Handlers for important information about exceptions thrown from modal [...]

Leave a Reply