如何构建我的 java 类 以不导致来自 JPype 的 NoClassDefFoundException?

How do I build my java classes to not result in NoClassDefFoundException from JPype?

我有一个 Netbeans 项目,其中包含我多年前编写的一些 Java 代码。我现在正在 python 中做一个新项目,但我的旧项目中有一个 Java class,它有一些我想使用的方便的 MIDI 代码,因为我到目前为止无法轻松转换为 python.

我使用 pip 安装 JPype,使用 Netbeans 构建我需要的 class,并将 .class 文件移动到与我的 python 文件相同的目录中。这是我的 python 调用 Java class 代码的删节部分,它被称为 "SoundTester" 并且在一个名为 "soundsynthesis".[=15 的包中=]

from jpype import startJVM, shutdownJVM, java, addClassPath, JClass, JInt
import jpype.imports
startJVM(convertStrings=False)
try:
    pass # Not sure why we need a pass here
    tester = JClass('soundsynthesis/SoundTester')
except Exception as e:
    print(f"Exception: {e}")
shutdownJVM()

结果是 Exception: java.lang.NoClassDefFoundError: soundsynthesis/SoundTester

请注意,如果我将 soundsynthesis/SoundTester 更改为 SoundTester,我会得到这个略有不同的异常:

Exception: java.lang.NoClassDefFoundError: SoundTester (wrong name: soundsynthesis/SoundTester)

我认为问题可能是由于我将 .class 文件从 Netbeans 项目中移出并移到了我的工作目录中,但我不知道如何解决该问题。我还尝试将 java 文件移动到我想要的目录中,然后只使用 javac 来构建它们。

我已经确保我的 python 版本和 jdk 都是 64 位的,因为那是一个类似问题的问题。

我解决了这个问题。也许不是最优雅的解决方案,但我修改了 Java classes 所以它们不在任何包中(或者更确切地说它们在默认包中)然后将它们移动到我的 python 工作目录并在那里用 javac 构建它们。

一旦我有了 java class 的 .class 个文件,我就可以调用 tester = JClass('SoundTester') 没有任何问题。

希望这对其他人有帮助。

这是路径规范的问题。的确,JNI 通常使用斜杠表示法来引用 类。但是,在这种情况下,JClass 调用 Java Class.forName() 方法,该方法需要点符号而不是 JNI。因此这个问题的解决方案是使用 JClass('soundsynthesis.SoundTester').

这里是一个在 jpype 中使用测试工具的例子。

import jpype
jpype.startJVM(classpath=['test/classes'], convertStrings=False)
j = jpype.JClass('jpype.common.Fixture') # success
j = jpype.JClass('jpype/common/Fixture') # fails

一般来说,JPype 使用 Java 本身的符号,而不是 JNI 强加的符号。有关更多示例,请参阅 quick guide.

中的 "Import a class without tld" 部分