scijava / scijava-common

A plugin framework and application container with built-in extensibility mechanism :electric_plug:
BSD 2-Clause "Simplified" License
85 stars 53 forks source link

NegativeArraySizeException from PrefService for Scripts with multiple Dataset inputs #442

Closed gselzer closed 1 year ago

gselzer commented 1 year ago

Writing the following Python script triggers the following error when running in Fiji's ScriptEditor. The issue comes from within PrefService. Note that this error will only appear the second time the script is run, as the first time it is run PrefService will not have yet cached the inputs from prior runs:

#@ Dataset d1
#@ Dataset d2
[INFO] Verifying GIF format
[ERROR] java.util.concurrent.ExecutionException: java.lang.RuntimeException: Module threw exception
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.scijava.ui.swing.script.TextEditor.evalScript(TextEditor.java:3506)
    at org.scijava.ui.swing.script.TextEditor.access$600(TextEditor.java:204)
    at org.scijava.ui.swing.script.TextEditor$5.execute(TextEditor.java:2793)
    at org.scijava.ui.swing.script.TextEditor$Executer$1.run(TextEditor.java:2558)
Caused by: java.lang.RuntimeException: Module threw exception
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:127)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:63)
    at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:225)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.NegativeArraySizeException
    at org.scijava.io.handle.DataHandle.readString(DataHandle.java:264)
    at io.scif.formats.GIFFormat$Parser.typedParse(GIFFormat.java:391)
    at io.scif.formats.GIFFormat$Parser.typedParse(GIFFormat.java:363)
    at io.scif.AbstractParser.parse(AbstractParser.java:244)
    at io.scif.AbstractParser.parse(AbstractParser.java:314)
    at io.scif.AbstractParser.parse(AbstractParser.java:53)
    at io.scif.AbstractReader.setSource(AbstractReader.java:271)
    at io.scif.services.DefaultInitializeService.initializeReader(DefaultInitializeService.java:91)
    at io.scif.img.ImgOpener.createReader(ImgOpener.java:483)
    at io.scif.img.ImgOpener.openImgs(ImgOpener.java:242)
    at io.scif.services.DefaultDatasetIOService.open(DefaultDatasetIOService.java:152)
    at io.scif.services.DefaultDatasetIOService.open(DefaultDatasetIOService.java:133)
    at io.scif.services.DefaultDatasetIOService.open(DefaultDatasetIOService.java:138)
    at io.scif.convert.FileToDatasetConverter.convert(FileToDatasetConverter.java:88)
    at org.scijava.convert.AbstractConvertService.convert(AbstractConvertService.java:125)
    at org.scijava.convert.AbstractDelegateConverter.convert(AbstractDelegateConverter.java:53)
    at org.scijava.convert.AbstractConvertService.convert(AbstractConvertService.java:125)
    at org.scijava.module.DefaultModuleService.load(DefaultModuleService.java:316)
    at org.scijava.module.DefaultModuleService.loadInput(DefaultModuleService.java:544)
    at org.scijava.module.DefaultModuleService.lambda$loadInputs$1(DefaultModuleService.java:346)
    at java.util.ArrayList.forEach(ArrayList.java:1259)
    at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1082)
    at org.scijava.module.DefaultModuleService.loadInputs(DefaultModuleService.java:346)
    at org.scijava.module.process.LoadInputsPreprocessor.process(LoadInputsPreprocessor.java:58)
    at org.scijava.module.ModuleRunner.preProcess(ModuleRunner.java:102)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:152)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:124)
    ... 6 more
ctrueden commented 1 year ago

I don't see PrefService anywhere in that stack trace. It looks like a bug in SCIFIO's FileToDatasetConverter to me...

gselzer commented 1 year ago

I don't see PrefService anywhere in that stack trace.

Good point, thanks, I may have been too quick to dismiss. DefaultModuleService.load() uses prefService.get to get a string value that is passed to the converter, and that value has been wrong in different situations, however I bet you're right that the issue is actually in FileToDatasetConverter.

imagejan commented 1 year ago

I can't reproduce (with scifio-0.42.0.jar on the classpath). @gselzer what were the datasets you selected in the first script run?

gselzer commented 1 year ago

I can't reproduce (with scifio-0.42.0.jar on the classpath). @gselzer what were the datasets you selected in the first script run?

@imagejan I think it was two copies of the blobs sample image. I'll be out of the office the rest of the week, though; I can check on Monday

imagejan commented 1 year ago

Alright, thanks for the additional details.

I can reproduce as long as the image title looks like a file name (e.g. blobs.gif), but can't trigger the error when renaming the images to something else (e.g. test and test-1) before the first run. So indeed, it might be an issue with FileToDatasetConverter trying to resolve the persisted values...

See https://github.com/scifio/scifio/issues/434.