views:

1580

answers:

3

We'd like a trace in our application logs of these exceptions - by default Java just outputs them to the console.

+1  A: 

There are two ways:

  1. /* Install a Thread.UncaughtExceptionHandler on the EDT */
  2. Set a system property: System.setProperty("sun.awt.exception.handler",MyExceptionHandler.class.getName());

I don't know if the latter works on non-SUN jvms.

--

Indeed, the first is not correct, it's only a mechanism for detecting a crashed thread.

Using Thread.UncaufhtExceptionHandler won't catch EDT exceptions. The EDT class catches all throwables and prints them out rather than letting them unwind the whole thread.
shemnon
You are also missing details about what is needed in the second option, the MyExceptionHandler class must have a handle(Throwable) instance method accessable and a no-args constructor accessable.
shemnon
+1  A: 

There is a distinction between uncaught exceptions in the EDT and outside the EDT.

Another question has a solution for both but if you want just the EDT portion chewed up...

classs AWTExceptionHandler {

  public void handle(Throwable t) {
    try {
      // insert your exception handling code here
      // or do nothing to make it go away
    } catch (Throwable t) {
      // don't let the exception get thrown out, will cause infinite looping!
    }
  }

  public static void registerExceptionHandler() {
    System.setProperty('sun.awt.exception.handler', AWTExceptionHandler.class.getName())
  }
}
shemnon
+2  A: 

A little addition to shemnons anwer:
The first time an uncaught RuntimeException (or Error) occurs in the EDT it is looking for the property "sun.awt.exception.handler" and tries to load the class associated with the property. EDT needs the Handler class to have a default constructor, otherwise the EDT will not use it.
If you need to bring a bit more dynamics into the handling story you are forced to do this with static operations, because the class is instantiated by the EDT and therefore has no chance to access other resources other than static. Here is the exception handler code from our Swing framework we are using. It was written for Java 1.4 and it worked quite fine there:

public class AwtExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(AwtExceptionHandler.class);

    private static List exceptionHandlerList = new LinkedList();

    /**
     * WARNING: Don't change the signature of this method!
     */
    public void handle(Throwable throwable) {
        if (exceptionHandlerList.isEmpty()) {
            LOGGER.error("Uncatched Throwable detected", throwable);
        } else {
            delegate(new ExceptionEvent(throwable));
        }
    }

    private void delegate(ExceptionEvent event) {
        for (Iterator handlerIterator = exceptionHandlerList.iterator(); handlerIterator.hasNext();) {
            IExceptionHandler handler = (IExceptionHandler) handlerIterator.next();

            try {
                handler.handleException(event);
                if (event.isConsumed()) {
                    break;
                }
            } catch (Throwable e) {
                LOGGER.error("Error while running exception handler: " + handler, e);
            }
        }
    }

    public static void addErrorHandler(IExceptionHandler exceptionHandler) {
        exceptionHandlerList.add(exceptionHandler);
    }

    public static void removeErrorHandler(IExceptionHandler exceptionHandler) {
        exceptionHandlerList.remove(exceptionHandler);
    }

}

Hope it helps.

Roland Schneider