处理Groovy SwingBuilder.doOutside中的异常

时间:2014-01-24 15:28:26

标签: groovy swingbuilder

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

我正在尝试处理SwingBuilder.doOutside{}中发生的异常。我使用了Thread.setDefaultUncaughtExceptionHandler(),但它似乎没有拦截doOutside{}中未被捕获的例外。

这是一个说明问题的示例程序。如果我从命令行运行它并单击 EDT Exception 按钮,我会在stderr上看到printStackTrace()结果。如果我单击 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()
    }
}

1 个答案:

答案 0 :(得分:0)

我查看了Groovy 1.8.9的SwingBuilder源代码,结果发现doOutside使用ExecutorService.submit()如果从EDT线程调用它:

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

submit()会返回Future,如上所示,它会被丢弃。 Future会捕获其异常,只有在您调用Future.get()时才会抛出异常。但这绝不会发生在doOutside()

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

注意:Future已替换为Groovy 2.1.0-rc-1中的简单Thread.start()(请参阅错误http://jira.codehaus.org/browse/GROOVY-5074)。这消除了异常捕获问题。