Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.java.lang.NoClassDefFoundError #296

Open
nicknamexiaozui opened this issue Jan 12, 2024 · 11 comments
Open

java.lang.java.lang.NoClassDefFoundError #296

nicknamexiaozui opened this issue Jan 12, 2024 · 11 comments
Labels
tech-support Need help to get things working

Comments

@nicknamexiaozui
Copy link

nicknamexiaozui commented Jan 12, 2024

The env

image
image
image
From a local installation ,run the code

import imagej
ij = imagej.init('G:\\Fiji.app')

image_url = 'https://imagej.net/images/clown.jpg'
jimage = ij.io().open(image_url)

image = ij.py.from_java(jimage)

ij.py.show(image, cmap='gray')

the result

D:\python_tool\.env\Scripts\python.exe D:\python_tool\de.py 
Traceback (most recent call last):
  File "ClassLoader.java", line 521, in java.lang.ClassLoader.loadClass
java.lang.java.lang.ClassNotFoundException: java.lang.ClassNotFoundException: net.imglib2.img.basictypelongaccess.unsafe.owning.OwningFloatUnsafe
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "org.jpype.manager.TypeManager.java", line -1, in org.jpype.manager.TypeManager.findClassByName
Exception: Java Exception
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "D:\python_tool\de.py", line 3, in <module>
    ij = imagej.init('G:\\Fiji.app')
  File "D:\python_tool\.env\lib\site-packages\imagej\__init__.py", line 1200, in init
    success = _create_jvm(ij_dir_or_version_or_endpoint, mode, add_legacy)
  File "D:\python_tool\.env\lib\site-packages\imagej\__init__.py", line 1424, in _create_jvm
    sj.start_jvm()
  File "D:\python_tool\.env\lib\site-packages\scyjava\_java.py", line 243, in start_jvm
    callback()
  File "D:\python_tool\.env\lib\site-packages\imglyb\util.py", line 26, in _java_setup
    Helpers = scyjava.jimport("net.imglib2.python.Helpers")
  File "D:\python_tool\.env\lib\site-packages\scyjava\_java.py", line 405, in jimport
    return jpype.JClass(class_name)
  File "D:\python_tool\.env\lib\site-packages\jpype\_jclass.py", line 99, in __new__
    return _jpype._getClass(jc)
java.lang.java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: net/imglib2/img/basictypelongaccess/unsafe/owning/OwningFloatUnsafe

So I don't have the ideal to fix it

@elevans
Copy link
Member

elevans commented Jan 12, 2024

Hi @nicknamexiaozui. Can you give me a little more information. What version of PyImageJ are you using? Can you run the PyImageJ doctor and post the output? See this page on how to use the imagej.doctor utility.

@ctrueden
Copy link
Member

ctrueden commented Jan 12, 2024

The NoClassDefFoundError here means that the imglib2-unsafe JAR file is missing. When wrapping a local Fiji installation, as is being attempted here, PyImageJ attempts to "mix in" this JAR from the remote Maven repository, supplementing Fiji's installed libraries. So my guess is that something went wrong downloading the imglib2-unsafe library? I have seen this error happen before, but unfortunately I cannot recall what triggered it in the previous cases. I also do not recall whether the imagej.doctor does any relevant checks that would shine any light on it, although I'm guessing not.

Definitely make sure you are running the newest PyImageJ version of course. As a workaround, you can download imglib2-unsafe-1.0.0.jar and place it into your G:\Fiji.app\jars folder. For good measure you might want to also download imglib2-imglyb-2.0.0.jar and install it into G:\Fiji.app\jars as well, since it is closely related library and also not shipped with Fiji by default IIRC.

Edit: Oh, from the screenshots above, I see your Maven is coming from G:\apache-maven-3.9.6. So you have a copy of Maven installed outside of conda... but the PyImageJ conda environment also installs a Maven into the environment... so maybe the two of them are not playing nicely together?

@nicknamexiaozui
Copy link
Author

nicknamexiaozui commented Jan 16, 2024

@ctrueden wrote:

The NoClassDefFoundError here means that the imglib2-unsafe JAR file is missing. When wrapping a local Fiji installation, as is being attempted here, PyImageJ attempts to "mix in" this JAR from the remote Maven repository, supplementing Fiji's installed libraries. So my guess is that something went wrong downloading the imglib2-unsafe library? I have seen this error happen before, but unfortunately I cannot recall what triggered it in the previous cases. I also do not recall whether the imagej.doctor does any relevant checks that would shine any light on it, although I'm guessing not.

Definitely make sure you are running the newest PyImageJ version of course. As a workaround, you can download imglib2-unsafe-1.0.0.jar and place it into your G:\Fiji.app\jars folder. For good measure you might want to also download imglib2-imglyb-2.0.0.jar and install it into G:\Fiji.app\jars as well, since it is closely related library and also not shipped with Fiji by default IIRC.

Edit: Oh, from the screenshots above, I see your Maven is coming from G:\apache-maven-3.9.6. So you have a copy of Maven installed outside of conda... but the PyImageJ conda environment also installs a Maven into the environment... so maybe the two of them are not playing nicely together?

Thank you for you answer.I download the two jars ,and place it into your G:\Fiji.app\jars folder

Now,it find another error
image
I started debugging because I was interested, now I'm going to give it up,Thank you, brother.

@nicknamexiaozui
Copy link
Author

nicknamexiaozui commented Jan 16, 2024

@elevans Thank you, brother.After following the documentation, the following message is output

Checking Python:
--> Python executable = D:\python_tool\.env\Scripts\python.exe

Checking environment:
--> It looks like you are NOT running inside a Conda environment.

Checking Python dependencies:
--> jgo: D:\python_tool\.env\lib\site-packages\jgo\__init__.py
--> scyjava: D:\python_tool\.env\lib\site-packages\scyjava\__init__.py
--> imglyb: D:\python_tool\.env\lib\site-packages\imglyb\__init__.py
--> pyimagej: D:\python_tool\.env\lib\site-packages\imagej\__init__.py

Checking Maven:
--> Maven executable = G:\apache-maven-3.9.6\bin\mvn.CMD
$ mvn -v
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: G:\apache-maven-3.9.6
Java version: 11.0.0.1, vendor: Oracle Corporation, runtime: C:\jdk-11.0.0.1
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Checking Java:
--> JAVA_HOME = C:\jdk-11.0.0.1
--> Java executable = C:\jdk-11.0.0.1\bin\java.EXE
$ java -version
openjdk version "11.0.0.1" 2023-05-09
OpenJDK Runtime Environment 18.9 (build 11.0.0.1+3-5)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.0.1+3-5, mixed mode)

Questions and advice for you:
--> Did you intend to activate a Conda environment?

@elevans
Copy link
Member

elevans commented Jan 18, 2024

Hi @nicknamexiaozui. Thanks, the PyImageJ doctor says your environment has all the components it needs, but the output from @ctrueden 's suggestion indicates that have some version skew with some of the JARs in your environment. We're not exactly sure how this might have happened but there are few things you can do to help us figure this out:

  1. Can you print out your classpath? You can do so by using this function while you initialize PyImageJ like this:
import imagej
import scyjava as sj

def print_classpath():
    System = sj.jimport('java.lang.System')
    import re
    classpath = re.split('[:;]', str(System.getProperty('java.class.path')))
    print("\n".join(classpath))

sj.when_jvm_starts(print_classpath)
ij = imagej.init('/path/to/fiji')
  1. Its possible that jgo, the package that pulls in the JARs from the maven repository, has pulled in an old version which is clashing. Clearing the cache could help. To do this, delete the C:\Users\User Name\.jgo folder. Initializing PyImageJ again without any parameters (i.e. ij = imagej.init()) will pull down the latest version of ImageJ2. See the initialization documentation for more info.

  2. If you download a new copy of Fiji or initialize PyImageJ with ij = imagej.init('sc.fiji:fiji') do you get the same error?

@nicknamexiaozui
Copy link
Author

@elevans i have no classpath,because my java version just has those files
image
How should I configure my classpath, or are there any files missing?

@ctrueden
Copy link
Member

@nicknamexiaozui Please try adding the code that @elevans gave you to your Python program. Specifically:

import scyjava as sj

def print_classpath():
    System = sj.jimport('java.lang.System')
    import re
    classpath = re.split('[:;]', str(System.getProperty('java.class.path')))
    print("\n".join(classpath))

sj.when_jvm_starts(print_classpath)

Put this block of code just prior to your imagej.init call. This will make it so that your runtime classpath gets printed out as soon as Java starts up (which is happening successfully with your setup). The printed classpath will tell us whether our theory is correct that you somehow ended up with two differently versioned copies of the imglib2-imglyb library in your environment.

@nicknamexiaozui
Copy link
Author

@ctrueden first,i delete the C:\Users\User Name.jgo and .imagej folder,then run @elevans gave me the code
image
run the code
image

@elevans
Copy link
Member

elevans commented Jan 19, 2024

@nicknamexiaozui Are you trying to run this in the Spyder IDE by any chance? This looks like it. I remember working with someone who was trying to use PyImageJ with the REPL inside Spyder and for some reasons that I don't understand it didn't work. Instead using the command prompt/terminal worked as intended. Can you try to initialize PyImageJ outside of the IDE, perhaps in a jupyter notebook?

EDIT: I checked if my memory was right on using spyder with PyImageJ and I was wrong. It works fine...not sure what I was remember then.

@ctrueden
Copy link
Member

@nicknamexiaozui Ahh, it seems that we didn't get the classpath printout because there are other when_jvm_starts callbacks that get registered by a helper library (imglyb) as soon as import imagej runs. To work around this, you could move the import imagej call below your callback registration. So the code would look like:

import scyjava as sj

def print_classpath():
    System = sj.jimport('java.lang.System')
    import re
    classpath = re.split('[:;]', str(System.getProperty('java.class.path')))
    print("\n".join(classpath))

sj.when_jvm_starts(print_classpath)

import imagej
ij = imagej.init('/path/to/fiji')

Of course, this is un-Pythonic, but it's only temporary for debugging purposes.

Hopefully with the code structured this way, we'll see the classpath printout before the crash with net.imglib2.python.Helpers or toNativeBool.

Also, please observe carefully the exact final error message. The TypeError: Class net.imglib2.python.Helpers is not found means that the classpath has no imglib2-imglyb.jar, whereas the no attribute 'toNativeBool' error means that the copy of imglib2-imglyb.jar being used is older than version 1.1.0 when that function was added.

Either way, I'm not sure how the situation is happening. It's not supposed to be necessary to download and copy thef imglib2-imglyb + imglib2-unsafe JARs into your local Fiji—rather, what is supposed to happen is that PyImageJ downloads them on demand using the jgo library and mixes them into your classpath. But there might be a bug where that isn't happening. If so, it would explain the "class not found" error. But then in that case, I don't understand why you would be getting the "no attribute 'toNativeBool'" error after that... unless you somehow dropped in imglib2-imglyb-1.0.0.jar to your Fiji.app rather than imglib2-imglyb-2.0.0.jar?

@elevans
Copy link
Member

elevans commented Jan 28, 2024

Hi @nicknamexiaozui, I'm just following up with you to see if you had a chance to try out @ctrueden suggested change to print out the classpath to help figure out whats going on your end. Did it work?

@ctrueden ctrueden added the tech-support Need help to get things working label Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tech-support Need help to get things working
Projects
None yet
Development

No branches or pull requests

3 participants