bonej-org / BoneJ2

Plugins for bone image analysis
BSD 2-Clause "Simplified" License
20 stars 12 forks source link

NoClassDefFoundError when initializing SciView #93

Closed rimadoma closed 6 years ago

rimadoma commented 6 years ago

SciView works when launched from IntelliJ, but when when it's installed into a local copy of Fiji with mvn -Dimagej.app.directory=/path/ -Ddelete.other.versions=true clean install then plug-in crashes with

[ERROR] Module threw error
java.lang.NoClassDefFoundError: com/jogamp/opengl/math/FloatUtil
    at cleargl.GLMatrix.setIdentity(GLMatrix.java:41)
    at cleargl.GLMatrix.getIdentity(GLMatrix.java:46)
    at graphics.scenery.Node.<init>(Node.kt:73)
    at graphics.scenery.Scene.<init>(Scene.kt:11)
    at graphics.scenery.SceneryBase.<init>(SceneryBase.kt:39)
    at sc.iview.SciView.<init>(SciView.java:48)
    at sc.iview.DefaultSciViewService.getOrCreateActiveSciView(DefaultSciViewService.java:110)
    at org.bonej.wrapperPlugins.SurfaceFractionWrapper.renderSurfaces(SurfaceFractionWrapper.java:201)
    at org.bonej.wrapperPlugins.SurfaceFractionWrapper.run(SurfaceFractionWrapper.java:125)
    at org.scijava.command.CommandModule.run(CommandModule.java:199)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:168)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:127)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:66)
    at org.scijava.thread.DefaultThreadService$3.call(DefaultThreadService.java:238)
    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.ClassNotFoundException: com.jogamp.opengl.math.FloatUtil
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 18 more

when it tries to initialize SciView.

Steps to reproduce

  1. git clone commit a91a706f251b266174fd19c5f3a57771dd4172c8
  2. Build and deploy packages to Fiji mvn -Dimagej.app.directory=/path/ -Ddelete.other.versions=true clean install
  3. Launch Fiji
  4. File > Open Samples > Bat Cochlea Volume
  5. Plugins > BoneJ > Fraction > Surface fraction
  6. Tick Render bone mesh
rimadoma commented 6 years ago

Just had a check, and this is not caused by the POM exclusions introduced in #86

rimadoma commented 6 years ago

Environment tested:

ctrueden commented 6 years ago

@rimadoma You cannot install SciView naively using the imagej-maven-plugin, because it has some native JARs that are not put into the correct places. You need to use the populate-fiji.sh script. I do want to improve the imagej-maven-plugin to fix all the edge cases involved, but it is rather far down the totem pole of priorities right now. Until the imagej-maven-plugin is improved, unfortunately, downstream components such as BoneJ2 that depend on SciView will thus transitively have the same installation issues.

rimadoma commented 6 years ago

@ctrueden Thanks for the tip! How would this affect installing BoneJ with SciView from the update site? Would a user also have to run the script?

ctrueden commented 6 years ago

Nope, the populate-fiji.sh script is for you as developer, to create a Fiji.app from which the JARs can be uploaded to the BoneJ update site. See also sciview_deploy.sh in the SciView repository, which takes the generated Fiji.app and actually uploads everything to the SciView update site. You could copy and paste these scripts—for now—into the BoneJ repository and use them to keep the BoneJ update site automatically up-to-date. Make sure you tweak them to enable the SciView update site for the generated Fiji.app, so that only the BoneJ-specific files get uploaded to BoneJ.

On the user side, they will then simply enable the SciView and BoneJ update sites, and get everything they need in the right places.

rimadoma commented 6 years ago

Is there anything else to using the script than calling ./populate-fiji.sh and then mvn install -Dimagej.app.directory=Fiji.app -Dmaven.test.skip=true for my stuff? Everything installs nicely, but calls to SciView just seem to freeze Fiji. @kephale Have you experienced anything similar?

ctrueden commented 6 years ago

Do not call mvn install -Dimagej.app.directory=Fiji.app -Dmaven.test.skip=true—the populate-fiji.sh already does that on line 66. It should take care of everything. If you invoke the imagej-maven-plugin again afterward, it will put back the native libraries into the wrong places, and there will be two copies of things.

calls to SciView just seem to freeze Fiji.

Does SciView work in a regular Fiji installation on that system with the SciView update site enabled? But freezes in the Fiji.app generated by populate-fiji.sh? If yes and yes, then you can do a directory diff between the two folders to see what is different.

rimadoma commented 6 years ago

Is the command on line 66 missing a Maven goal on purpose?

SciView works on the system when Fiji is launched from IntelliJ, I'll have to get back to you on what's different between a regular installation and the one created by the script.

ctrueden commented 6 years ago

Is the command on line 66 missing a Maven goal on purpose?

The default goal of anything extending pom-scijava is install.

I'll have to get back to you on what's different between a regular installation and the one created by the script.

Sounds good, please ping back when you have more info.

rimadoma commented 6 years ago

Okay, several discoveries: 1) SciView from the update site works on regular Fiji installation 2) This is because the update site hosts newer versions of SciView and its dependencies than declared in POM of version 0.0.1, namely:

diff-sciview-update-bonej Difference between what BoneJ installs from dependency on sciview-0.0.1 v. what's on the update site (Java 8 updates appear because this branch still depends on pom-scijava 17.1.1)

rimadoma commented 6 years ago

In the light of this new info I tried hacking my POM with a dependency to the newer scenery (with exclusions) and graphics.scenery:spirvcrossj, which did lead to a new NoClassDefFoundError.

rimadoma commented 6 years ago

This problem can solved by using the installation script populate-fiji.sh. In addition to running the script, you have to manually copy the following packages to the Fiji.app/jars/ directory: populate-fiji-hack.txt. You might be able to get around the manual step by adding the necessary (runtime) dependencies to the POM, but I won't investigate this now.

In any case this issue is temporary, because in future the increasing integration between Fiji and SciView should solve these dependency issues, as SciView will work in your Fiji installation out-of-the-box.

ctrueden commented 5 years ago

Yeah, I certainly want to smarten up the scijava-maven-plugin's copy-jars goal to do the right thing in more cases, and eliminate the need for complicated Fiji populator scripts. SciView also suffers from this issue right now, and eventually we will go through the edge cases and make them work one by one. And then BoneJ2 should reap the benefits as well.