-->

UncaughtExceptionHandler not catching some excepti

2019-07-21 22:27发布

问题:

I have created an UncaughtExceptionHandler as shown in this article.

I have also registered this handler to catch exceptions in all threads like this:

    Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

However, it is missing some exceptions:

Exception occurred during event dispatching:
java.lang.RuntimeException: Critical error!
    at com.acme.MyClass.myMethod(MyClass.java:46)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
    at java.awt.EventQueue.access$000(EventQueue.java:84)
    at java.awt.EventQueue$1.run(EventQueue.java:602)
    at java.awt.EventQueue$1.run(EventQueue.java:600)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:178)
    at java.awt.Dialog$1.run(Dialog.java:1046)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
    at java.awt.EventQueue.access$000(EventQueue.java:84)
    at java.awt.EventQueue$1.run(EventQueue.java:602)
    at java.awt.EventQueue$1.run(EventQueue.java:600)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$2.run(EventQueue.java:616)
    at java.awt.EventQueue$2.run(EventQueue.java:614)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Why is it missing exceptions like this?

回答1:

Probably the thread in which this exception is thrown already has its own uncaught exception handler. In this case the default handler is not used. You can check this by calling the getUncaughtExceptionHandler() method on the relevant thread (which is the event dispatcher thread here).

It could also be that this thread belongs to a special ThreadGroup, which handles the exception instead of delegating it to the default handler.

In both cases, you could explicitly set your handler as the handler of this thread with the setUncaughtExceptionHandler() method.



回答2:

java.awt.EventDispatchThread#processException care about sun.awt.exception.handler system property. This bug is reported to be fixed in Java 7.

For Java 6 next is perfectly working for me:

import java.lang.Thread.UncaughtExceptionHandler;

import org.apache.log4j.Logger;

/**
 * @see java.awt.EventDispatchThread.processException
 * @see java.lang.Thread.dispatchUncaughtException
 * @see java.lang.ThreadGroup.uncaughtException
 * @author Mykhaylo Adamovych
 */
public class DefaultUncaughtExceptionHandler implements UncaughtExceptionHandler {
    public static final String SP_SUN_AWT_EXCEPTION_HANDLER = "sun.awt.exception.handler";
    static {
        if (Thread.getDefaultUncaughtExceptionHandler() == null)
            Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
        if (System.getProperty(SP_SUN_AWT_EXCEPTION_HANDLER) == null)
            System.setProperty(SP_SUN_AWT_EXCEPTION_HANDLER, DefaultUncaughtExceptionHandler.class.getName());
    }

    public static void initialize() {
        // load class and perform initialization
    }

    public void handle(Throwable e) {
        uncaughtException(Thread.currentThread(), e);
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        if (!(e instanceof ThreadDeath))
            Logger.getLogger(e.getStackTrace()[0].getClassName()).error("Exception in thread \"" + t.getName() + "\"", e);
    }
}