【问题标题】:Why bother with setting the "sun.awt.exception.handler" property?为什么要设置“sun.awt.exception.handler”属性?
【发布时间】:2011-04-26 18:00:51
【问题描述】:

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

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 注册异常处理程序?

【问题讨论】:

    标签: java swing awt uncaught-exception


    【解决方案1】:

    EDT 类(java.awt.EventDispatchThread,不要在 javadoc 中查找,这个类是 package private)自从 AWT 起源以来发生了很大变化.

    JDK6 中,您可以看到这个类现在可以正确处理 EDT 内部发生的异常。当前版本的异常处理有点复杂:

    • 如果您已设置 sun.awt.exception.handler 财产, 那么你的处理程序将被调用 开发人员抛出的每个异常 在 EDT 内调用的代码 (与以前的JDK兼容 确保版本)。
    • 否则,将出现任何异常 重新抛出,因此将停止当前的 EDT,以及任何默认值 UncaughtExceptionHandler 将是 能够抓住它,就像你的 sn-p 演示。

    BUT(这是非常重要),如果你仔细看EDT的代码,你会发现如果出现异常,这个机制就不起作用了发生在 EDT 显示模式对话框时(我猜这是因为 EDT 和 EventQueue 管理相当复杂,我什至敢说“混乱”:a那里有很多代码看起来像黑客)。

    在这种情况下,异常将被记录到System.err,除非您设置了sun.awt.exception.handler 属性。拥有默认的UncaughtExceptionHandler 将无济于事。

    所以我对此的看法是,是的,您仍然应该使用sun.awt.exception.handler 属性,除非您可以确定您的应用程序不使用模式对话框(不要忘记JOptionPane 对话框也是模态的)。

    【讨论】:

    【解决方案2】:

    您调用了setDefaultUncaughtExceptionHandler 而不是setUncaughtExceptionHandler。 (如果存在SecurityManager:前者需要RuntimePermission setDefaultUncaughtExceptionHandler;后者需要SecurityManager.checkAccess(Thread)。)

    【讨论】:

    • Hawtin 我希望我的 JavaFX UI 在出现未捕获的错误时弹出一个消息框。你能澄清一下我应该使用哪个电话吗?
    • @Anil 如果它是一个不受信任的插件/WebStart 应用程序,它必须是setUncaughtExceptionHandler。理论上我相信你应该只在事件线程上使用 JavaFX,所以你只需要设置一次(但要确保在正确的线程上)。如果没有实现的组件,AWT EDT 可以退出并被另一个线程替换,因此如果这很重要,那么这可能是不够的。
    • Hawtin JavaFX 也使用 Tasks 和 Workers 作为后台线程,我正在使用它们。我不知道这是否“正确”,但这是我所做的:在控制器 - UI 线程中,我调用了 `Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t , Throwable e) { OkCancelController okc = null; okc = replaceSceneContent(okc, "ok_cancel.fxml", "App has an error:" + e.getMessage()); } });`
    猜你喜欢
    • 1970-01-01
    • 2021-10-19
    • 2021-02-22
    • 2019-05-23
    • 2011-03-23
    • 2023-03-12
    • 2011-07-24
    • 2010-11-10
    • 1970-01-01
    相关资源
    最近更新 更多