我创建了一个UncaughtExceptionHandler,如this article所示。
我还注册了这个处理程序来捕获所有线程中的异常:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
然而,它缺少一些例外:
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)
为什么会遗漏这样的例外?
答案 0 :(得分:1)
抛出此异常的线程可能已经有了自己的未捕获异常处理程序。在这种情况下,不使用默认处理程序。您可以通过调用相关线程(这里是事件调度程序线程)上的getUncaughtExceptionHandler()
方法来检查这一点。
也可能是这个线程属于一个特殊的ThreadGroup
,它处理异常而不是将它委托给默认的处理程序。
在这两种情况下,您都可以使用setUncaughtExceptionHandler()
方法将处理程序显式设置为此线程的处理程序。
答案 1 :(得分:0)
java.awt.EventDispatchThread#processException
关注sun.awt.exception.handler
系统属性。据报道,此bug在Java 7中得到修复。
对于Java 6,接下来对我来说非常有用:
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);
}
}