[ImageJ-devel] Problem with Exporting Runnable Jar

Curtis Rueden ctrueden at wisc.edu
Fri Jan 31 16:21:32 CST 2014


Hi Jay,

> I typically deploy JEX as a runnable jar via the Eclipse export.
> However, the exported jar fails to run while the Eclipse project
> encounters no such issue. The export process seems to break the IJ2
> portion of the application making it impossible at the moment to
> attempt to deploy the JEX version with the IJ2 enhancements. I've
> isolated the issue to being purely related to the IJ2 set of jars that
> I included into the project.

This problem is almost certainly due to the fact that the SciJava Common
plugin mechanism stores a file in each JAR at:
/META-INF/json/org.scijava.plugin.Plugin. And when combining multiple JARs
into an uber-JAR, those files need to be aggregated together rather than
overwriting one another. We ran into the very same problem using the
maven-assembly-plugin to build an uber-JAR. Our workaround is here:

https://github.com/imagej/imagej/blob/imagej-2.0.0-beta-7.6/bin/gen-jar-with-deps.sh

Which calls the AnnotationCombiner class from SciJava Common:
https://github.com/scijava/scijava-common/blob/scijava-common-2.9.0/src/main/java/org/scijava/annotations/AnnotationCombiner.java

In the future we will look into switching to maven-shade-plugin to create
such an uber-JAR.

But I still don't know if/how you can do that with Eclipse's "Export
executable JAR" feature.

> I also noticed that the during the successful eclipse run there is a
> line which reads... [WARNING] Overridden plugin
> ij.plugin.LutLoader("3-3-2 RGB") is blacklisted  Do you think there is
> any connection?

Nope, that warning is unrelated and can be safely ignored.

> I know that Eclipse, when it exports a runnable jar, creates a
> relatively non-standard jar hierarchy (jarinjar), which might be the
> issue

Hmm, in that case, it may be possible to improve SciJava Common to find
such META-INF in nested JARs. Feel free to file a PR against scijava-common
(https://github.com/scijava/scijava-common) for this feature if you really
need it.

To pursue that, you'd want to inspect your uber-JAR using the Java JAR
command line tool (e.g., "jar tf myUberJar.jar") to see exactly what got
put in there. Maybe unpack it ("jar xf myUberJar.jar") and then examine any
nested JARs, as well.

The relevant code in scijava-common is here:
https://github.com/scijava/scijava-common/blob/scijava-common-2.9.0/src/main/java/org/scijava/annotations/Index.java#L130

The code uses ClassLoader.getResources() to access all annotations within
META-INF/json across all JAR files on the classpath. If Eclipse really
embeds JARs inside other JARs, you'd have to smarten up that method to
support that somehow, which would be an unfortunate addition in complexity.

Easier would be to avoid using uber-JARs at all and instead just ship with
all your JAR libraries separately. Then all the annotations will be
discovered as expected.

Or you could somehow run the AnnotationCombiner across all of your JARs
when building your uber-JAR, perhaps using the maven-shade-plugin. If you
structured JEX as a Maven project it would be relatively straightforward to
use that, and do your releases from the command line, too.

Sorry I can't be more helpful, but we really avoid doing things in ways
that cannot be automated from the command line.

Regards,
Curtis



On Mon, Jan 20, 2014 at 10:45 PM, Jay Warrick <jay.w.warrick at gmail.com>wrote:

> Hi Guys,
>
> I have had some success with incorporating IJ2 plugins but ran into an
> issue during deployment that I wonder if you have run into before. I
> typically deploy JEX as a runnable jar via the Eclipse export. However, the
> exported jar fails to run while the Eclipse project encounters no such
> issue. The export process seems to break the IJ2 portion of the application
> making it impossible at the moment to attempt to deploy the JEX version
> with the IJ2 enhancements. I've isolated the issue to being purely related
> to the IJ2 set of jars that I included into the project. I did this by
> making a separate project with only IJ2 jars (which also includes the IJ1
> jar) and a simple static main that uses IJ2 to run the "Fill" plugin on a
> tif that is on my computer. The program runs successfully when run from
> eclipse but produces an error when exported and run as a runnable jar. Here
> is the script, the output from the Eclipse run, output from the jar run,
> and list of imported jars for the simple test project. Note that I had to
> add the "static{DefaultLegacyService.preinit();}" to the class to get
> things to work in the presence of the IJ1 jar that is included.
>
>
>
>
>
>
> Do you have any suggestions? I appears that it thinks that the
> DefaultLUTService is invalid per "Caused by:
> java.lang.IllegalArgumentException: Invalid service:
> imagej.data.lut.DefaultLUTService". I also noticed that the during the
> successful eclipse run there is a line which reads... [WARNING]
> Overridden plugin ij.plugin.LutLoader("3-3-2 RGB") is blacklisted  Do you
> think there is any connection?
>
> I know that Eclipse, when it exports a runnable jar, creates a relatively
> non-standard jar hierarchy (jarinjar), which might be the issue given the "Caused
> by: java.lang.IllegalArgumentException: URI is not hierarchical at
> java.io.File.<init>(File.java:418)" error.
>
> I'm not well versed enough in maven or other such dependency management
> systems to be able to export something for you to import (unless it is
> super easy and I just don't know the correct menu options :-) But, in case
> it helps, this is how I built the small test project. To import the jars, I
> import the jar files as files directly into a package called lib so the jar
> files are not just referenced but actually a part of the project (probably
> not best practice but found it effective for our project and haven't had
> issues with the other 25 jars that we use in the JEX project). Then I
> configure the build path and "Add Jars" selecting the jars that are
> imported into the project. During export, I choose to package required
> libraries into generated jar.
>
> Thanks for any insight,
>
> Jay
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20140131/fbe2324f/attachment.html>


More information about the ImageJ-devel mailing list