I have been working with Java threads in order to provide a GUI platform for running processes in a pipeline. I've managed to work through a number of issues with SwingWorker
, but this one is seemingly incomprehensible.
My SwingWorker
looks like:
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);
}
};
I use this to run a Java process; a simplified version of the launching code is:
try{
Class<?> target_class = Class.forName(main_class);
CommandInstance instance = (CommandInstance)target_class.newInstance();
CommandFunctions.ProcessState state = instance.execute(args);
}catch (InvocationTargetException e){
throw new PipelineException("Java process '" + this.getName() + "." + uid + "' encountered exception: " + e.getCause().getMessage());
}catch (Exception e){
throw new PipelineException("JavaProcess encountered exception invoking target: " + e.getMessage());
}
The process itself has a try-catch block around code which loads some data from a file. However, despite being wrapped in two layers of try-catch blocks (actually three, if you count the done()
method), when the loader throws an Exception it prints a stack trace, the Exception is not caught, and the SwingWorker
thread hangs (the code halts so I can no longer force an interrupt).
This sort of Exception hanging has occurred in other circumstances as well; most puzzlingly, in other -- seemingly identical -- cases the Exception is caught and the thread exits gracefully.
I haven't been able to find much about this online, although I'll continue to search. I am no expert in Swing threading, so I was hoping someone might have an insight about this sort of issue. I'd love it to be a very stupid error on my part :)
EDIT: @Adrian, here is the stack trace. It seems to stall half way... very strange:
java.io.EOFException
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:399)
at mgui.io.standard.nifti.Nifti1Dataset.readVolBlob(Nifti1Dataset.java:2179)
at mgui.io.standard.nifti.Nifti1Dataset.readDoubleVol(Nifti1Dataset.java:1916)
at mgui.io.standard.nifti.NiftiVolumeLoader.setGrid3DBlocking(NiftiVolumeLoader.java:186)
at mgui.io.domestic.shapes.VolumeFileLoader.setGrid3D(VolumeFileLoader.java:237)
at mgui.io.domestic.shapes.VolumeFileLoader.getGrid3D(VolumeFileLoader.java:139)
at mgui.io.domestic.shapes.VolumeFileLoader.getGrid3D(VolumeFileLoader.java:97)
at minc.MincFunctions.create_volume_atlas_masks(MincFunctions.java:5240)
at minc.MincFunctions.run_command(MincFunctions.java:153)
at mgui.command.CommandInstance.execute(CommandInstance.java:87)
at mgui.pipelines.JavaProcess.run(JavaProcess.java:141)
at mgui.pipelines.PipelineFunctions.launchBlockingPipelineProcess(PipelineFunctions.java:238)
at mgui.pipelines.PipelineFunctions.launchPipelineProcess(PipelineFunctions.ja
EDIT2: Debugging in Eclipse, I can halt at a breakpoint on the line where it is thrown (well, one step before); the stack trace at that point is:
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