Вызов Java из Python
Каков наилучший способ вызова java из python?
(jython и RPC для меня не подходят).
Я слышал о JCC: http://pypi.python.org/pypi/JCC/1.9
генератор кода С++ для вызова Java из С++/Python
Но это требует компиляции всех возможных вызовов; Я бы предпочел другое решение.
Я слышал о JPype: http://jpype.sourceforge.net/
tutorial: http://www.slideshare.net/onyame/mixing-python-and-java
import jpype
jpype.startJVM(path to jvm.dll, "-ea")
javaPackage = jpype.JPackage("JavaPackageName")
javaClass = javaPackage.JavaClassName
javaObject = javaClass()
javaObject.JavaMethodName()
jpype.shutdownJVM()
Это похоже на то, что мне нужно.
Однако последний выпуск - с января 2009 года, и я вижу, что люди не могут скомпилировать JPype.
Является ли JPype мертвым проектом?
Есть ли другие альтернативы?
С уважением,
Дэвид
Ответы
Ответ 1
Вот мое резюме этой проблемы: 5 способов вызова Java из Python
http://baojie.org/blog/2014/06/16/call-java-from-python/ (кэш)
Короткий ответ: Jpype работает очень хорошо и доказано во многих проектах (например, python-pipepipe), но Pyjnius быстрее и проще, чем JPype
Я пробовал Pyjnius/Jnius, JCC, javabridge, Jpype и Py4j.
Py4j немного сложно использовать, поскольку вам нужно запустить шлюз, добавив еще один уровень хрупкости.
Ответ 2
Вы также можете использовать Py4J. На главной странице есть пример и много документации, но по сути вы просто вызываете методы Java из своего кода на Python, как если бы они были методами python:
from py4j.java_gateway import JavaGateway
gateway = JavaGateway() # connect to the JVM
java_object = gateway.jvm.mypackage.MyClass() # invoke constructor
other_object = java_object.doThat()
other_object.doThis(1,'abc')
gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method
В отличие от Jython, одна часть Py4J работает в Python VM, поэтому она всегда "обновлена" с последней версией Python, и вы можете использовать библиотеки, которые не работают на Jython (например, lxml). Другая часть выполняется на виртуальной машине Java, которую вы хотите вызвать.
Связь осуществляется через сокеты вместо JNI, а Py4J имеет собственный протокол (для оптимизации определенных случаев, для управления памятью и т.д.).
Отказ от ответственности: я являюсь автором Py4J
Ответ 3
Pyjnius.
Документы: http://pyjnius.readthedocs.org/en/latest/
Github: https://github.com/kivy/pyjnius
На странице github:
Модуль Python для доступа к классам Java в качестве классов Python с использованием JNI.
PyJNIus - это "работа в процессе".
Краткая информация
>>> from jnius import autoclass
>>> autoclass('java.lang.System').out.println('Hello world') Hello world
>>> Stack = autoclass('java.util.Stack')
>>> stack = Stack()
>>> stack.push('hello')
>>> stack.push('world')
>>> print stack.pop() world
>>> print stack.pop() hello
Ответ 4
Я на OSX 10.10.2, и мне удалось использовать JPype.
Устранены проблемы с установкой с Jnius (другие тоже), Javabridge установил, но дал таинственные ошибки, когда я пытался его использовать, PyJ4 имеет это неудобство при запуске сервера шлюза в Java сначала, JCC не будет устанавливать. Наконец, JPype закончил работу. Там поддерживается fork JPype на Github. Он имеет основные преимущества: (а) он устанавливается правильно и (б) он может очень эффективно преобразовывать массивы java в массив numpy (np_arr = java_arr[:]
)
Процесс установки:
git clone https://github.com/originell/jpype.git
cd jpype
python setup.py install
И вы должны иметь возможность import jpype
Следующая демо работала:
import jpype as jp
jp.startJVM(jp.getDefaultJVMPath(), "-ea")
jp.java.lang.System.out.println("hello world")
jp.shutdownJVM()
Когда я попытался вызвать свой собственный Java-код, мне пришлось сначала скомпилировать (javac ./blah/HelloWorldJPype.java
), и мне пришлось изменить путь JVM от значения по умолчанию (в противном случае вы получите необъяснимые ошибки "class not found" ). Для меня это означало изменение команды startJVM на:
jp.startJVM('/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/MacOS/libjli.dylib', "-ea")
c = jp.JClass('blah.HelloWorldJPype')
# Where my java class file is in ./blah/HelloWorldJPype.class
...
Ответ 5
В последнее время я интегрировал много нового в Python, включая Java. Самый надежный метод, который я нашел, - использовать IKVM и оболочку С#.
IKVM имеет небольшое приложение, которое позволяет вам использовать любой Java JAR и преобразовывать его непосредственно в DLL.Net. Он просто переводит байт-код JVM в байт-код CLR. Подробнее см. http://sourceforge.net/p/ikvm/wiki/Ikvmc/.
Преобразованная библиотека ведет себя как родная библиотека С#, и вы можете использовать ее без использования JVM. Затем вы можете создать проект оболочки С# DLL и добавить ссылку на преобразованную DLL.
Теперь вы можете создать некоторые заглушки-оболочки, которые вызывают методы, которые вы хотите открыть, и пометить эти методы как DllEport. Подробнее см. fooobar.com/questions/68129/....
DLL-оболочка действует так же, как и родная библиотека C, с экспортированными методами, которые выглядят так же, как экспортированные методы C. Вы можете подключиться к ним, используя ctype, как обычно.
Я пробовал его с Python 2.7, но он должен работать и с 3.0. Работает на Windows и Linux
Если вы используете С#, то это, вероятно, лучший подход, чтобы попытаться интегрировать почти что-нибудь в python.
Ответ 6
Я только начинаю использовать JPype 0.5.4.2 (июль 2011), и похоже, что он хорошо работает...
Я на Xubuntu 10.04
Ответ 7
Если вы находитесь в Python 3, есть вилка JPype, называемая JPype1-py3
pip install JPype1-py3
Это работает для меня на OSX/Python 3.4.3. (Возможно, вам понадобится export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version
)
from jpype import *
startJVM(getDefaultJVMPath(), "-ea")
java.lang.System.out.println("hello world")
shutdownJVM()
Ответ 8
Я предполагаю, что если вы можете перейти с С++ на Java, тогда вы все настроены. Я видел продукт такого рода, о котором вы хорошо говорите. Так получилось, что мы использовали CodeMesh. Я специально не поддерживаю этого поставщика или не делаю никаких заявлений об относительном качестве их продукта, но я видел, что он работает с довольно высоким объемом.
Я бы сказал в целом, что, если это вообще возможно, я бы рекомендовал избегать прямой интеграции через JNI, если можно. Некоторый простой подход к сервису REST или архитектура на основе очереди будут проще упрощать и диагностировать. Вы можете получить вполне приличную производительность, если тщательно использовать такие развязанные технологии.
Ответ 9
Благодаря собственному опыту, пытающемуся запустить некоторый код java изнутри python, я похожа на то, как код python запускается в java-коде в python, мне не удалось найти прямую методологию.
Мое решение моей проблемы состояло в том, чтобы запустить этот Java-код в виде скриптов beanshell, вызвав интерпретатор beanshell как оболочку commnad из моего кода на Python после редактирования кода Java во временном файле с соответствующими пакетами и переменными.
Если то, о чем я говорю, полезно в любом случае, я рад помочь вам поделиться более подробными сведениями о моих решениях.