How can I catch AWT thread exceptions in Java?
Asked Answered
T

4

18

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

Theogony answered 18/9, 2008 at 19:4 Comment(0)
A
10

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...

class 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())
  }
}
Ammeter answered 18/9, 2008 at 21:27 Comment(2)
No need to catch throwable. There will be no infinite looping. java.awt.EventDispatchThread.handleException is catching any exceptions for you.Leninist
There saids classs AWTExceptionHandlerWoodsia
R
17

Since Java 7, you have to do it differently as the sun.awt.exception.handler hack does not work anymore.

Here is the solution (from Uncaught AWT Exceptions in Java 7).

// Regular Exception
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());

// EDT Exception
SwingUtilities.invokeAndWait(new Runnable()
{
    public void run()
    {
        // We are in the event dispatching thread
        Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler());
    }
});
Rhetorician answered 9/1, 2015 at 10:57 Comment(6)
According to the source you linked, it is not necessary to set an UncaughtExceptionHandler specifically for the EDT if it is the same as the default UncaughtExceptionHandler for all threads.Chaperon
My example is not very realistic (same UncaughtExceptionHandler), the thing is you can set a specific UncaughtExceptionHandler just for the EDTRhetorician
But yes you can also set one time a default handler and manage the exception here (whether you are or not in the EDT)Rhetorician
What would you do if a new EDT is started, for example for a modal dialog? Is there a way to get notified of this?Chaperon
I'm not a big AWT specialist but is it possible to have more than one EDT running ?Rhetorician
It is necessary with modal dialogs, because if you open a modal dialog from the primary EDT, you must pause it so it can continue after the statement that opened the dialog, but within the dialog, you need an event loop. Ergo, you need to start a new one for the duration of the dialog. Of course, only one EDT will be "running" because the other is paused, but they are distinct threads.Chaperon
A
10

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...

class 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())
  }
}
Ammeter answered 18/9, 2008 at 21:27 Comment(2)
No need to catch throwable. There will be no infinite looping. java.awt.EventDispatchThread.handleException is catching any exceptions for you.Leninist
There saids classs AWTExceptionHandlerWoodsia
A
3

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.

Azar answered 20/9, 2008 at 6:50 Comment(0)
N
0

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.

Nerty answered 18/9, 2008 at 19:8 Comment(2)
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.Ammeter
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.Ammeter

© 2022 - 2024 — McMap. All rights reserved.