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

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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】:

有两种方式:

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

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

--

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

【讨论】:

使用 Thread.UncaufhtExceptionHandler 不会捕获 EDT 异常。 EDT 类捕获所有可抛出对象并将它们打印出来,而不是让它们展开整个线程。 您还缺少有关第二个选项中所需内容的详细信息,MyExceptionHandler 类必须具有可访问的句柄(Throwable)实例方法和可访问的无参数构造函数。

以上是关于如何在 Java 中捕获 AWT 线程异常?的主要内容,如果未能解决你的问题,请参考以下文章

线程“主”java.awt.AWTError 中的异常:未找到辅助技术

Java子线程中的异常处理(通用)

java基础子线程任务发生异常,主线程事务如何回滚?

多线程情况下如何捕获线程中的异常?

Thread如何捕获异常

Thread如何捕获异常