Java SwingWorker上的异常不可捕获

Java SwingWorker上的异常不可捕获,java,multithreading,swing,exception-handling,swingworker,Java,Multithreading,Swing,Exception Handling,Swingworker,我一直在使用Java线程,以便为在管道中运行进程提供GUI平台。我已经设法解决了SwingWorker的许多问题,但这个问题似乎令人费解 我的SwingWorker看起来像: SwingWorker<Boolean,Object> worker = new SwingWorker<Boolean,Object>() { @Override public Boolean doInBackground() { re

我一直在使用Java线程,以便为在管道中运行进程提供GUI平台。我已经设法解决了SwingWorker的许多问题,但这个问题似乎令人费解

我的
SwingWorker
看起来像:

SwingWorker<Boolean,Object> worker = new SwingWorker<Boolean,Object>() {
         @Override 
        public Boolean doInBackground() {
             return launchBlockingPipelineProcess(process, instance, project, logger, state);
         }

         @Override
         protected void done(){
             boolean success = false;
             try{
                 success = get();
                 if (!success){
                     state.setTaskFailed(true);
                     }
                 if (process.getStatus().equals(Status.Interrupted)){
                     state.setTaskInterrupted(true);
                     }
             }catch (Exception ex){
                state.setTaskFailed(true); 
                }

             processCompleted(process, success, state);
         }

    };
EDIT2:在Eclipse中调试时,我可以在抛出它的行上的断点处停止(好的,一步之前);该点的堆栈跟踪为:

Nifti1Dataset.readVolBlob(short) line: 2179 
Nifti1Dataset.readDoubleVol(short) line: 1916   
NiftiVolumeLoader.setGrid3DBlocking(Grid3D, int, ProgressUpdater) line: 186 
NiftiVolumeLoader(VolumeFileLoader).setGrid3D(Grid3D, int, ProgressUpdater) line: 237   
NiftiVolumeLoader(VolumeFileLoader).getGrid3D(VolumeInputOptions, int, ProgressUpdater) line: 139   
NiftiVolumeLoader(VolumeFileLoader).getGrid3D(int) line: 97 
MincFunctions.create_volume_atlas_masks() line: 5278    
MincFunctions.run_command(String) line: 153 
MincFunctions(CommandInstance).execute(String[]) line: 87   
JavaProcess.run(String[], long) line: 141   
PipelineFunctions.launchBlockingPipelineProcess(PipelineProcessInstance, String, InterfaceProject, String, PipelineState) line: 238 
PipelineFunctions.launchPipelineProcess(PipelineProcessInstance, String, InterfaceProject, String, boolean, PipelineState) line: 78 
PipelineFunctions.launchPipelineProcess(PipelineProcessInstance, boolean, PipelineState) line: 52   
PipelineProcessInstance.launch(boolean) line: 187   
InterfacePipeline.launch(boolean) line: 388 
PipelineLauncher.doInBackground() line: 57  
PipelineLauncher.doInBackground() line: 1   
SwingWorker$1.call() line: 277  
FutureTask$Sync.innerRun() line: 303    
SwingWorker$2(FutureTask<V>).run() line: 138    
PipelineLauncher(SwingWorker<T,V>).run() line: 316  
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886   
ThreadPoolExecutor$Worker.run() line: 908   
Thread.run() line: 662  
Nifti1Dataset.readVolBlob(短)行:2179
Nifti1Dataset.readDoubleVol(短)行:1916
setGrid3DBlocking(Grid3D,int,ProgressUpdater)行:186
NiftivolumLoader(VolumeFileLoader).setGrid3D(Grid3D,int,ProgressUpdater)行:237
NiftiVolumeLoader(VolumeFileLoader).getGrid3D(VolumeInputOptions,int,ProgressUpdater)行:139
NiftivolumLoader(VolumeFileLoader).getGrid3D(int)行:97
MincFunctions.create\u volume\u atlas\u masks()行:5278
MincFunctions.run_命令(字符串)行:153
MincFunctions(CommandInstance).execute(字符串[])行:87
运行(字符串[],长)行:141
PipelineFunctions.launchBlockingPipelineProcess(PipelineProcessInstance,String,InterfaceProject,String,PipelineState)行:238
PipelineFunctions.launchPipelineProcess(PipelineProcessInstance,String,InterfaceProject,String,boolean,PipelineState)行:78
PipelineFunctions.launchPipelineProcess(PipelineProcessInstance,boolean,PipelineState)行:52
PipelineProcessInstance.launch(布尔)行:187
InterfacePiline.launch(布尔)行:388
PipelineLauncher.doInBackground()行:57
PipelineLauncher.doInBackground()行:1
SwingWorker$1.call()行:277
FutureTask$Sync.innerRun()行:303
SwingWorker$2(FutureTask).run()行:138
PipelineLauncher(SwingWorker).run()行:316
ThreadPoolExecutor$Worker.runTask(Runnable)行:886
ThreadPoolExecutor$Worker.run()行:908
Thread.run()行:662

是可以从
SwingWorker
的方法
done()
中获取
异常
,但需要严格命名每个线程,尤其是,我还没有找到另一种方法来解决这个问题的可能性

我解决了一个类似的表问题,在AWT线程绘制UI时不进行干扰。 我使用
invokeLater()
将我的线程与UI线程同步


更多详情请参见。

@Adrian,谢谢你的建议;我不认为我直接从
SwingWorker
线程进行任何UI更新;我确实会对
JTree
节点进行更新,以指示流程的成功或失败,但我使用发布/流程机制来实现这一点,这应该确保所有UI更新都从EDT调用:

这些是从执行管道调用的侦听器处理程序:

@Override
public void pipelineTaskTerminated(DynamicPipelineEvent event, PipelineTask task) {
    publish(task);
}

@Override
public void pipelineTaskUpdated(DynamicPipelineEvent event, PipelineTask task) {
    // Here we can publish the update to a task status
    publish(task);

}
以下是处理方法:

@Override
protected void process(List<PipelineTask> tasks) {

    // Update task listeners on the Event-Dispatch Thread
    for (int i = 0; i < tasks.size(); i++){
        PipelineTask task = tasks.get(i);
        InterfacePipeline pipeline = task.getPipeline();
        if (pipeline != null){
            task.fireStatusChanged();
            }
        }

}
除此之外(潜在的信息),对
JTree
的调用也不会导致UI的更新,尽管它是从EDT调用的。强制更新树的唯一方法是单击节点本身。可能是一个新线程的问题,但它可能是相关的

我将通过消除线程中任何潜在的UI更新来完成代码和实验,并查看是否可以通过这种方式防止问题。。。请继续关注:)


编辑:即使完全删除这些更新,也会引发相同的异常…

可能是错误而不是异常。你查过了吗?请打印堆栈跟踪。@Adrian by Error implementations仅返回
get exception
感谢您的响应;我对命名线程的重要性有点困惑?在我的例子中,我将done()命令包装在一个try-catch块中,它在线程本身或原始EDT调用中都没有被捕获。也就是说,我甚至没有得到一个
java.util.concurrent.ExecutionException
您是如何模拟这个异常的,因为所有的异常都被重定向到SwingWorker,所以肯定还有另一个问题,你是否用GCNope杀死了这个线程或一些woodo,我没有杀死它或在它上使用任何实用程序,只是作为SwingWorker运行它,它提供了这个中止的堆栈跟踪。我可以在抛出异常的行的断点处停止;我在OP中添加了堆栈跟踪。只是为了确保,没有应用一些自定义的外观,因为其中一些是invokeAndWait()的必需用法。谢谢,我使用的是自定义L&F,但我只是将其设置为默认值,并得到相同的问题(异常暂停和缺少树更新)。感谢所有的回复!
@Override
public void pipelineTaskTerminated(DynamicPipelineEvent event, PipelineTask task) {
    publish(task);
}

@Override
public void pipelineTaskUpdated(DynamicPipelineEvent event, PipelineTask task) {
    // Here we can publish the update to a task status
    publish(task);

}
@Override
protected void process(List<PipelineTask> tasks) {

    // Update task listeners on the Event-Dispatch Thread
    for (int i = 0; i < tasks.size(); i++){
        PipelineTask task = tasks.get(i);
        InterfacePipeline pipeline = task.getPipeline();
        if (pipeline != null){
            task.fireStatusChanged();
            }
        }

}
public void taskStatusChanged(PipelineTaskEvent e){
    if (model == null) return;
    model.nodeStructureChanged(this);
    tree.repaint();
}