QuPath ImageJ Plugins Discovery for Scripting

Hi all,

This is a question as much as a summary of what I discovered when using non-default IJ1 plugins within QuPath (0.1.2 [I think] and 0.2.0).

QuPath defines a location for ImageJ Plugins under preferences > ImageJ > ImageJ plugins directory

So suppose I am adding MorphoLibJ.jar to this previously defined location

I then can find the plugin in ImageJ under Plugins > MorphoLibJ > Etc...

However if I need to use the MorphoLibJ API from a QuPath script, it does not find the classes

In order to find and load the MorphoLibJ for use in a QuPath script, I need the MorphoLibJ.jar to be inside the extensions directory inside the folder defined under Preferences > Extensions > QuPath User Directory

Which brings me to the question: What is the rationale in not letting QuPath load the jars in ImageJ plugins directory directly as well? In my mind, having a jar for ImageJ available within QuPath should allow me to call upon those classes from within a QuPath script directly. Currently I see two options.

  1. Duplicate the Jars and make the distinction between the ones where I will programmatically access them in QuPath and those I will use within QuPath’s ImageJ instance interactively (or using IJ.run). Bit messy
  2. Make the ImageJ plugins directory a subdirectory inside QuPath User Directory/Extensions. Guess it solves the duplication issue, but now the ImageJ plugins are user-specific, and kind of kills the point of having these two preferences separate.

Another option would be to have QuPath load the jars in the ImageJ plugins directory on startup, and not just the ones in QuPath User Directory/Extensions

In my mind, the last paragraph makes the most sense, but would involve changes in the QuPath code, whereas the others do not, but are a bit wonky.

It would be good to know what the “official” recommendation is, so that I can write up a protocol for our users, as we often benefit from external ImageJ plugins not within QuPath.

All the best

Oli

I don’t remember if there is one, or if it’s just the way I wrote it originally and never had a reason to revisit.

Personally, I’d do/have done the first – but I haven’t needed this often enough to be annoyed by its limitations.

I’d be mildly concerned that having a lot of unnecessary jars on the classpath could be problematic – in particular if using Fiji, where there may be a lot of jars that are incompatible with QuPath (e.g. older versions of JavaCPP, amongst others). It might not be, since they would be added to the classpath after startup, but I’m not totally sure… and I’d rather err on the side of avoiding the classpath where I can.

A possible alternative (I haven’t tested): does creating symbolic links help at all?

2 Likes

Follow-up: I forget if I’ve mentioned this before (I don’t think so), but you can optionally add a startup.groovy script to your user directory. If the script is there and activated in the preferences, this can perform some custom initialization automatically on startup.

I’m not entirely sure if the startup script is a good idea or not. In any case, you need to select it in the preferences to reduce the risk of a nefarious script causing havoc.

With that in mind, you might try this (also untested) idea to load some more jars:

def file = new File('/your/jar/file.jar')
getQuPath().addExtensionJar(file)

I suppose in this case you could also include a startup extension that does a similar initialization… and is probably harder to break than the script.

1 Like

I guess as long as the usage is simple it’s not a problem. I’ll add this to our documentation. Thank you.

I agree that adding a whole bunch of jars is risky, especially the Fiji stuff.

Do you think this might become an issue for QuPath down the line, as it cannot benefit from some cool plugins that start coming out (CLIJ2 for instance)? Is there something new about having Fiji in QuPath? I know the Java versions were an issue, among many other things… but I think that some of those have been addressed. No rush but wanted to know if there was anything in that direction.

Thanks again

Oli

2 Likes

I look into it periodically, but have never got it working properly…

Well, what I could do was launch QuPath from Fiji if I started Fiji using Java 11 or later (there is a launch method in QuPath specifically to make this easier). This gave me access to things like the StarDist Fiji plugin directly from QuPath. Somehow it mostly worked, despite the incompatible jars, perhaps because of when they were first loaded.

However, I encountered a lot of other issues with Fiji not really liking Java 11 very much at all. This included frequent freezes on startup when nothing would work.

My feeling at the moment is that QuPath benefits a lot from not needing to maintain compatibility with many other tools – for example, through being able to embrace Java 11 fully and quickly.

For those reasons I’d rather concentrate on making exchange of data possible for now, rather than direct integration. Fiji goes all-in for Java 11 then that could change, but I suspect that could be very difficult given quite how big a change it is from Java 8.

1 Like