在Groovy SwingBuilder.doOutside中处理异常
(这是Groovy 1.8.9。该问题在Groovy 2.1.0-rc-1中得到修复) 我正在尝试处理在Groovy SwingBuilder.doOutside中处理异常,groovy,swingbuilder,Groovy,Swingbuilder,(这是Groovy 1.8.9。该问题在Groovy 2.1.0-rc-1中得到修复) 我正在尝试处理SwingBuilder.doOutside{}中发生的异常。我使用了Thread.setDefaultUncaughtExceptionHandler(),但它似乎没有拦截doOutside{}中的未捕获异常 下面是一个示例程序,说明了这个问题。如果从命令行运行此命令并单击EDT Exception按钮,我会在stderr上看到printStackTrace()结果。如果单击“外部异常”,则不
SwingBuilder.doOutside{}
中发生的异常。我使用了Thread.setDefaultUncaughtExceptionHandler()
,但它似乎没有拦截doOutside{}
中的未捕获异常
下面是一个示例程序,说明了这个问题。如果从命令行运行此命令并单击EDT Exception按钮,我会在stderr上看到printStackTrace()
结果。如果单击“外部异常”,则不会显示任何内容。我做错了什么
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()
}
}
我查看了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.get()
时才会抛出异常本身。但在doOutside()
中,这种情况永远不会发生
因此,我需要在传递给doOutside()
的闭包中放置一个try-catch,以便能够注意到那里发生了异常
注意:Groovy 2.1.0-rc-1中的Future
被一个简单的Thread.start()
替换(请参见bug)。这就消除了异常捕获问题