8

下面是一些捕获事件调度线程上抛出的异常的代码:

package com.ndh.swingjunk;

import java.awt.EventQueue;

import javax.swing.JFrame;

public class EntryPoint {

    public static void main(String[] args) {
        Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
//      System.setProperty("sun.awt.exception.handler", MyExceptionHandler.class.getName());

        EventQueue.invokeLater(new Runnable() 
        {
            public void run() 
            {
                new SomeWindow("foo").setVisible(true);
            }
        });
    }
}

class SomeWindow extends JFrame {
    public SomeWindow(String title) {
        this.setTitle(title);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        throw new RuntimeException("hello");
    }
}

我已经看到警告说事件调度线程上引发的异常不会由 UncaughtExceptionHandler 处理,但我的示例似乎并非如此;无论注册行是被注释掉还是留在里面,它的工作原理都是一样的。我的例子是否搞砸了,或者注册异常处理程序sun.awt.exception.handler不再需要?

4

2 回答 2

15

The EDT class (java.awt.EventDispatchThread, don't look for it in the javadoc, this class is package private) has changed a lot since the origins of AWT.

In JDK6, you can see that this class now can properly handle exceptions occuring inside the EDT. Exception handling is a bit complex in the current version:

  • if you have set the sun.awt.exception.handler property, then your handler will be called for every exception thrown by developer's code called inside the EDT (compatibility with previous JDK versions is ensured).
  • otherwise, any exception will be rethrown, hence will stop the current EDT, and any default UncaughtExceptionHandler will be able to catch it, as your snippet demonstrates.

BUT (and this is very important), if you carefully look at the code of EDT, you'll see that this mechanism won't work if the exception occurs in the EDT while a modal dialog is displayed (I guess this is because EDT and EventQueue management is quite complicated and I would even dare say "messy": a lot of code looks like hacks in there).

In this exact situation, exceptions will be logged to System.err, except if you have set the sun.awt.exception.handler property. Having a default UncaughtExceptionHandler will not help.

So my take on this is that, YES, you should still bother with sun.awt.exception.handler property, except if you can say for sure that your application doesn't use modal dialogs (don't forget that JOptionPane dialogs are also modal).

于 2011-04-27T07:46:06.787 回答
2

你打电话setDefaultUncaughtExceptionHandler而不是setUncaughtExceptionHandler. (如果 aSecurityManager存在:前者需要RuntimePermission setDefaultUncaughtExceptionHandler;后者需要SecurityManager.checkAccess(Thread)。)

于 2011-04-26T18:09:17.257 回答