Как мне построить мои java классы, чтобы не привести к NoClassDefFoundException из JPype? - PullRequest
0 голосов
/ 28 марта 2020

У меня есть проект Netbeans с кодом Java, который я писал много лет go. Сейчас я делаю новый проект в python, но у меня есть класс Java в моем старом проекте, в котором есть какой-то удобный MIDI-код, который я хотел бы использовать, поскольку я до сих пор не мог легко перевести на python .

Я использовал pip для установки JPype, использовал Netbeans для создания нужного мне класса и переместил файл .class в тот же каталог, что и мой python файл. Вот сокращенная часть моего python кода для вызова класса Java, который называется «SoundTester» и находится в пакете под названием «soundsynthesis».

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

Обратите внимание, что если я изменю звуковой синтез / SoundTester на SoundTester , я получу это немного другое исключение:

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

Я думаю, что проблема может быть в том, что я переместил файлы .class из проекта Netbeans в мой рабочий каталог, но я не знаю, как решить эту проблему. Я также попытался переместить файлы java в нужный каталог и просто использовать javac для их создания.

Я гарантировал, что моя версия python и jdk оба 64-битные, так как это было похоже на вопрос.

Ответы [ 2 ]

2 голосов
/ 07 апреля 2020

Это проблема со спецификацией пути. Это правда, что JNI обычно ссылается на классы, используя обозначение sla sh. Однако в этом случае 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. Дополнительные примеры см. В разделе «Импорт класса без tld» в кратком руководстве .

0 голосов
/ 29 марта 2020

Я решил проблему. Возможно, это не самое элегантное решение, но я изменил классы Java, чтобы они не были в каком-либо пакете (или, скорее, они были в пакете по умолчанию), а затем переместил их в мой рабочий каталог python и собрал их с javac там.

Как только у меня были .class-файлы моих java классов, я мог без проблем вызвать tester = JClass('SoundTester').

Надеюсь, это поможет кому-то еще.

...