Вызов 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 во временном файле с соответствующими пакетами и переменными.

Если то, о чем я говорю, полезно в любом случае, я рад помочь вам поделиться более подробными сведениями о моих решениях.