【问题标题】:How can I catch AWT thread exceptions in Java?如何在 Java 中捕获 AWT 线程异常?
【发布时间】:2010-09-10 21:07:00
【问题描述】:

我们希望在我们的应用程序日志中跟踪这些异常 - 默认情况下,Java 只是将它们输出到控制台。

【问题讨论】:

    标签: java swing exception-handling awt


    【解决方案1】:

    从 Java 7 开始,您必须采取不同的做法,因为 sun.awt.exception.handler hack 不再起作用。

    Here is the solution(来自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());
        }
    });
    

    【讨论】:

    • 根据你链接的来源,如果它与所有线程的默认UncaughtExceptionHandler相同,则不需要专门为EDT设置UncaughtExceptionHandler。
    • 我的例子不太现实(同样UncaughtExceptionHandler),问题是你可以为EDT设置一个特定的UncaughtExceptionHandler
    • 但是是的,您也可以设置一次默认处理程序并在此处管理异常(无论您是否在 EDT)
    • 如果一个新的 EDT 被启动,例如一个模态对话框,你会怎么做?有没有办法得到通知?
    • 我不是 AWT 专家,但可以运行多个 EDT 吗?
    【解决方案2】:

    在 EDT 内和 EDT 外未捕获的异常是有区别的。

    Another question has a solution for both 但如果您只想咀嚼 EDT 部分...

    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())
      }
    }
    

    【讨论】:

    • 无需捕获可投掷物。不会有无限循环。 java.awt.EventDispatchThread.handleException 正在为您捕获任何异常。
    • 那里说classs AWTExceptionHandler
    【解决方案3】:

    shemnon的回答的一点补充:
    第一次在 EDT 中发生未捕获的 RuntimeException(或错误)时,它正在寻找属性“sun.awt.exception.handler”并尝试加载与该属性关联的类。 EDT 需要 Handler 类有一个默认的构造函数,否则 EDT 不会使用它。
    如果您需要在处理故事中引入更多动态,则必须使用静态操作来执行此操作,因为该类是由 EDT 实例化的,因此没有机会访问静态以外的其他资源。这是我们正在使用的 Swing 框架中的异常处理程序代码。它是为 Java 1.4 编写的,在那里运行良好:

    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);
        }
    
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

      有两种方式:

      1. /* 在 EDT 上安装 Thread.UncaughtExceptionHandler */
      2. 设置系统属性: System.setProperty("sun.awt.exception.handler",MyExceptionHandler.class.getName());

      我不知道后者是否适用于非 SUN jvm。

      --

      确实,第一个是不正确的,它只是一种检测崩溃线程的机制。

      【讨论】:

      • 使用 Thread.UncaufhtExceptionHandler 不会捕获 EDT 异常。 EDT 类捕获所有可抛出对象并将它们打印出来,而不是让它们展开整个线程。
      • 您还缺少有关第二个选项中所需内容的详细信息,MyExceptionHandler 类必须具有可访问的句柄(Throwable)实例方法和可访问的无参数构造函数。
      猜你喜欢
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 2010-12-27
      相关资源
      最近更新 更多