1

(这是 Groovy 1.8.9。问题已在 Groovy 2.1.0-rc-1 中修复)

我正在尝试处理SwingBuilder.doOutside{}. 我用过Thread.setDefaultUncaughtExceptionHandler(),但它似乎没有拦截doOutside{}.

这是一个说明问题的示例程序。如果我从命令行运行它并单击EDT Exception按钮,我printStackTrace()会在 stderr 上看到结果。如果我单击Outside Exception,则没有任何显示。我究竟做错了什么?

import groovy.swing.SwingBuilder

class ExceptionTest {
    static main(args) {
        Thread.setDefaultUncaughtExceptionHandler(
            { thread, exception ->
                System.err.println "thread ${thread.getName()}"
                exception.printStackTrace()
            } as Thread.UncaughtExceptionHandler)

        def swing = new SwingBuilder()

        def testEDTButton = swing.button('EDT exception')
        testEDTButton.actionPerformed = { throw new Exception("EDT exception") }

        def testOutsideButton = swing.button('Outside Exception')
        testOutsideButton.actionPerformed = { swing.doOutside { throw new Exception("Exception outside") } }

        def frame = swing.frame(title: 'Test exception reporting') {
            vbox {
                widget(testEDTButton)
                widget(testOutsideButton)
            }
        }
        frame.pack()
        frame.show()
    }
}
4

1 回答 1

0

我查看了 Groovy 1.8.9 的 SwingBuilder 源代码,结果发现doOutsideExecutorService.submit()是从 EDT 线程调用的:

private static final ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
...
DEFAULT_EXECUTOR_SERVICE.submit(c)

如上所示,submit()返回的 aFuture会被丢弃。AFuture捕获其异常,并且仅在您调用Future.get(). 但这永远不会发生在doOutside().

因此,我需要在传递给的闭包中放置一个 try-catch,doOutside()以便能够注意到那里发生了异常。

注意:在 Groovy 2.1.0-rc-1 中Future被替换为简单Thread.start()的(参见错误https://issues.apache.org/jira/browse/GROOVY-5074)。这消除了异常捕获问题。

于 2014-01-24T17:09:48.740 回答