[ImageJ-devel] [LOCI ImageJ] IJ2 Plugin Service

Johannes Schindelin Johannes.Schindelin at gmx.de
Wed Apr 30 12:51:31 CDT 2014


On Wed, 30 Apr 2014, Curtis Rueden wrote:

> > when I export the application as a runnable jar, ij.plugin()service
> > returns all the Command.class plugins but 0 plugins of type
> > JEXPlugin.class
> This is an issue we have discussed before: Eclipse creates uberjars using a
> "jar-in-jar" approach, and SciJava Common's plugin mechanism does not read
> the metadata out of a jar-in-jar.

Please note that the jar-in-jar poses no problem, unless the ClassLoader
used to access them is broken: it needs to support the getResources() call
properly and find the resource files contained in the nested .jar files.

However, in the reported case I believe it is not triggered by the uber
jar or jar-in-jar scenario.

Background: The internal technique behind the plugins uses annotation
processors run at compile time. They basically look at each file that has
a @Plugin annotation and write out index files that get included into the
.jar files.

Except that Eclipse -- violating the Java specification -- does not run
annotation processors. At least not by default, and even if you switch it
on (manually, for each and every project you maintain, one by one), it
*still* only runs them on full builds (i.e. after Project>Clean).

So it looks to me that in the reported case, the annotation processor is
never run, and as a consequence, the index file is never written, and
therefore it cannot be found at runtime.

Of course, Eclipse being such a prevalent platform to develop in, we tried
to come up with a workaround: whenever the annotation indexes are read, a
class called "EclipseHelper" tries to detect whether it needs to create
the index files because Eclipse failed to run the annotation processors.

This works amazingly well because many developers have written unit tests
and run them before bundling .jar files manually. These unit tests verify
that plugins work, of course, which is why the EclipseHelper works around
the problem successfully in most cases.

Also, here is a lesson for everybody choosing to learn from our past
mistakes and experiences: any possible convenience of uber jars is
outweighed multiple times over by the disadvantages it incurs to users: it
makes updating really costly (every time it's time to update, a new
monster .jar needs to be downloaded), it makes collaboration between
projects difficult at best, and it certainly asks for version skew.


More information about the ImageJ-devel mailing list