如何在Java中捕获AWT线程异常?

如何在Java中捕获AWT线程异常?,java,swing,exception-handling,awt,Java,Swing,Exception Handling,Awt,我们希望在应用程序日志中跟踪这些异常-默认情况下,Java只将它们输出到控制台。有两种方法: /*在EDT上安装Thread.UncaughtExceptionHandler*/ 设置系统属性: System.setProperty(“sun.awt.exception.handler”,MyExceptionHandler.class.getName()) 我不知道后者是否适用于非SUN JVM -- 实际上,第一个是不正确的,它只是一种检测崩溃线程的机制。EDT中的未捕获异常和EDT之外的未

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

有两种方法:

  • /*在EDT上安装Thread.UncaughtExceptionHandler*/
  • 设置系统属性: System.setProperty(“sun.awt.exception.handler”,MyExceptionHandler.class.getName()) 我不知道后者是否适用于非SUN JVM

    --


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

    EDT中的未捕获异常和EDT之外的未捕获异常之间有区别

    但是如果你只想把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())
      }
    }
    
    对shemnons anwer的一点补充:
    EDT中第一次出现未捕获的运行时异常(或错误)时,它正在查找属性“sun.awt.exception.handler”,并尝试加载与该属性关联的类。EDT需要处理程序类具有默认构造函数,否则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);
        }
    
    }
    

    希望它能有所帮助。

    自从Java7以来,由于
    sun.awt.exception.handler
    hack不再起作用,您必须以不同的方式进行操作

    (来自)


    使用Thread.UncaufhtExceptionHandler不会捕获EDT异常。EDT类捕获所有Throwable并将其打印出来,而不是让它们释放整个线程。您还缺少关于第二个选项中所需内容的详细信息,MyExceptionHandler类必须具有可访问的句柄(Throwable)实例方法和可访问的无参数构造函数。无需捕获Throwable。不会有无限循环。java.awt.EventDispatchThread.handleException正在为您捕获任何异常。根据您链接的源,这里说,如果所有线程的UncaughtExceptionHandler与默认UncaughtExceptionHandler相同,则无需专门为EDT设置UncaughtExceptionHandler。我的示例不太现实(same
    UncaughtExceptionHandler
    ),问题是,您可以仅为EDT设置一个特定的
    UncaughtExceptionHandler
    ,但您也可以一次性设置一个默认处理程序并在此处管理异常(无论您是否在EDT中)。如果启动了新的EDT,您会怎么做,例如,对于模式对话框?有没有办法得到通知?我不是一个大的AWT专家,但有可能有一个以上的EDT运行?
    // 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());
        }
    });