Module init error and Preprocessor Error

When working in Modern mode in Fiji/ImageJ2, when I try to run commands like “Add Axis…” or “Add Data…”, I have the following bug :

org.scijava.module.MethodCallException: Error executing method: net.imagej.plugins.commands.restructure.AddData#initAll
    at org.scijava.module.MethodRef.execute(MethodRef.java:73)
    at org.scijava.module.AbstractModule.initialize(AbstractModule.java:82)
    at org.scijava.module.process.InitPreprocessor.process(InitPreprocessor.java:60)
    at org.scijava.module.ModuleRunner.preProcess(ModuleRunner.java:104)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:156)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
    at org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.scijava.module.MethodRef.execute(MethodRef.java:69)
    ... 11 more
Caused by: java.lang.NullPointerException
    at net.imagej.plugins.commands.restructure.AddData.initAxisName(AddData.java:298)
    at net.imagej.plugins.commands.restructure.AddData.initAll(AddData.java:157)
    ... 16 more
org.scijava.module.MethodCallException: Error executing method: net.imagej.plugins.commands.restructure.AddAxis#initAll
    at org.scijava.module.MethodRef.execute(MethodRef.java:73)
    at org.scijava.module.AbstractModule.initialize(AbstractModule.java:82)
    at org.scijava.module.process.InitPreprocessor.process(InitPreprocessor.java:60)
    at org.scijava.module.ModuleRunner.preProcess(ModuleRunner.java:104)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:156)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
    at org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.scijava.module.MethodRef.execute(MethodRef.java:69)
    ... 11 more
Caused by: java.lang.NullPointerException
    at net.imagej.plugins.commands.restructure.AddAxis.initAxisName(AddAxis.java:236)
    at net.imagej.plugins.commands.restructure.AddAxis.initAll(AddAxis.java:134)
    ... 16 more

With the message : Module failed to initialize. The error is caused because the ds (Dataset) object is still null. It seems that the module initializes itself before the Preprocessor, or more likely, the Preprocessor (SingleInputPreprocessor which should) is not called at all.

Does someone has an Idea of the reason ?

Cheers,

Cyril

Okay, I investigated the problem inside ImageJ FX by creating some dummy preprocessor :

@Plugin(type = PreprocessorPlugin.class, priority=Priority.VERY_HIGH_PRIORITY)
public class DummyActiveDatasetPreprocessor extends ActiveDatasetPreprocessor{
        
    
    @Parameter
    ImageDisplayService imgDisplayService;
    
    @Parameter
    DisplayService displayService;
    
    @Parameter
    DatasetService datasetSetvice;
    
    @Override
    public Dataset getValue() {
        System.out.println("All I do is win !"); // checks if the method is executed
        System.out.println(imgDisplayService); // display the image service
        System.out.println(super.getValue()); // prints null
        System.out.println(imgDisplayService.getActiveDataset()); // prints null
        System.out.println(imgDisplayService.getActiveImageDisplay()); // prints null
        System.out.println(displayService.getActiveDisplay(ImageDisplay.class)); // prints the active displays successfully
        System.out.println(imgDisplayService.getActiveDataset(displayService.getActiveDisplay(ImageDisplay.class))); // prints the active dataset successfully
        return imgDisplayService.getActiveDataset(displayService.getActiveDisplay(ImageDisplay.class)); // Solves the problem :-D
    }
}

Since this problem is present also in Fiji, I guess it’s not a problem specific to ImageJFX (which uses anyway the display model). The most troubling thing about the bug is that ImageDisplayService.getActiveImageDisplay() returns null while displayService.getActiveDisplay(ImageDisplay.class) (found inside getActiveImageDisplay) returns the active ImageDisplay.

Okay, I guess I found the problem. At least, in my ImageJ Context, the default ImageDisplayService is not the DefaultImageDisplayService but the LegacyImageDisplayService so when using the DisplayService, everything works fine but when using the ImageDisplayService, it only tries to find images coming from ImageJ1 but fails so it returns null. I don’t know if this error is the same in Fiji in Modern Mode. It could be that the switch between the mode doesn’t switch the priority of the ImageDisplayServices.

1 Like

Glad you found the issue. Yes, the imagej-legacy component is very hacky in quite a few ways. It does not play nice with other UIs, for one thing. (We definitely want it to do so—problems like the one you found should be considered bugs—but we don’t have time to fix it right now.)

For ImageJFX, you might actually want to exclude that dependency completely. Unless you really need ImageJ1 stuff—which from the ImageJFX release notes, it seems is unsupported so far anyway?

I wanted to support legacy plugins, especially biology oriented plugins. I will think about it.

Just a quick follow-up that we removed imagej-legacy as a hard dependency of imagej—it is now optional.

In my experience, supporting legacy plugins from UIs other than the actual ImageJ 1.x UI is extremely difficult. It can be done in many cases, but not all. Especially troublesome are plugins that make hard assumptions about the ImagePlus being tied an ImageWindow which is AWT-based.

Happy to elaborate further if you are really serious about supporting legacy plugins.