Llamando a Java desde Python

¿Cuál es la mejor manera de llamar a Java desde python? (jython y RPC no son una opción para mí).

He oído hablar de JCC: http://pypi.python.org/pypi/JCC/1.9 un generador de código C ++ para llamar a Java desde C ++ / Python Pero esto requiere comstackr todas las llamadas posibles; Preferiría otra solución.

He escuchado sobre 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() 

Esto parece lo que necesito. Sin embargo, la última versión es de enero de 2009 y veo personas que no comstackn JPype.

¿Es JPype un proyecto muerto?

¿Hay otras alternativas?

Saludos, David

Aquí está mi resumen de este problema: 5 formas de llamar a Java desde Python

http://baojie.org/blog/2014/06/16/call-java-from-python/ (en caché )

Respuesta corta: Jpype funciona bastante bien y está probado en muchos proyectos (como python-boilerpipe), pero Pyjnius es más rápido y más simple que JPype

He probado Pyjnius / Jnius, JCC, javabridge, Jpype y Py4j.

Py4j es un poco difícil de usar, ya que necesitas iniciar una puerta de enlace y agregar otra capa de fragilidad.

También puedes usar Py4J . Hay un ejemplo en la página principal y mucha documentación, pero básicamente, solo llama a los métodos Java desde su código de Python como si fueran métodos de 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 

A diferencia de Jython, una parte de Py4J se ejecuta en la máquina virtual de Python, por lo que siempre está “actualizada” con la última versión de Python y puede usar bibliotecas que no se ejecutan bien en Jython (por ejemplo, lxml). La otra parte se ejecuta en la máquina virtual Java a la que desea llamar.

La comunicación se realiza a través de sockets en lugar de JNI y Py4J tiene su propio protocolo (para optimizar ciertos casos, para administrar la memoria, etc.)

Descargo de responsabilidad: soy el autor de Py4J

Pyjnius.

Docs: http://pyjnius.readthedocs.org/en/latest/

Github: https://github.com/kivy/pyjnius

Desde la página de github:

Un módulo de Python para acceder a las clases de Java como clases de Python utilizando JNI.

PyJNIus es un “trabajo en progreso”.

Vista rápida

 >>> 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 

Estoy en OSX 10.10.2, y tuve éxito en el uso de JPype.

Al encontrarse con problemas de instalación con Jnius ( otros también lo han hecho ), Javabridge instaló, pero cometió errores misteriosos cuando intenté usarlo, PyJ4 tiene este inconveniente de tener que iniciar un servidor Gateway en Java primero, que JCC no instalaría. Finalmente, JPype terminó trabajando. Hay una bifurcación mantenida de JPype en Github. Tiene las principales ventajas de que (a) se instala correctamente y (b) puede convertir arrays Java de manera muy eficiente a una matriz np_arr = java_arr[:] ( np_arr = java_arr[:] )

El proceso de instalación fue:

 git clone https://github.com/originell/jpype.git cd jpype python setup.py install 

Y deberías poder import jpype

La siguiente demo funcionó:

 import jpype as jp jp.startJVM(jp.getDefaultJVMPath(), "-ea") jp.java.lang.System.out.println("hello world") jp.shutdownJVM() 

Cuando intenté llamar a mi propio código Java, primero tuve que comstackr ( javac ./blah/HelloWorldJPype.java ), y tuve que cambiar la ruta JVM de la predeterminada (de lo contrario obtendré errores inexplicables de “clase no encontrada”) . Para mí, esto significó cambiar el comando startJVM a:

 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 ... 

Si estás en Python 3, hay una bifurcación de JPype llamada JPype1-py3

 pip install JPype1-py3 

Esto me funciona en OSX / Python 3.4.3. (Es posible que necesite export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version )

 from jpype import * startJVM(getDefaultJVMPath(), "-ea") java.lang.System.out.println("hello world") shutdownJVM() 

Estoy empezando a usar JPype 0.5.4.2 (julio de 2011) y parece que está funcionando muy bien …
Estoy en Xubuntu 10.04

Últimamente he estado integrando muchas cosas en Python, incluyendo Java. El método más robusto que he encontrado es usar IKVM y un envoltorio de C #.

IKVM tiene una aplicación pequeña y ordenada que le permite tomar cualquier JAR de Java y convertirlo directamente a .Net DLL. Simplemente traduce el código de bytes JVM al código de bytes CLR. Consulte http://sourceforge.net/p/ikvm/wiki/Ikvmc/ para obtener más información.

La biblioteca convertida se comporta como una biblioteca C # nativa, y puede usarla sin necesidad de la JVM. Luego, puede crear un proyecto contenedor de C # DLL y agregar una referencia a la DLL convertida.

Ahora puede crear algunos apéndices de contenedor que llaman a los métodos que desea exponer y marcar esos métodos como DllEport. Consulte https://stackoverflow.com/a/29854281/1977538 para obtener más información.

La DLL de envoltorio actúa como una biblioteca C nativa, con los métodos exportados que se parecen a los métodos C exportados. Puedes conectarte a ellos usando ctype como siempre.

Lo he probado con Python 2.7, pero también debería funcionar con 3.0. Funciona en Windows y Linux

Si por casualidad usas C #, entonces este es probablemente el mejor enfoque que puedes probar al integrar casi cualquier cosa en python.

Supongo que si puedes pasar de C ++ a Java, estás listo. He visto que un producto del tipo que mencionas funciona bien. Como sucede el que utilizamos fue CodeMesh . No estoy respaldando específicamente a este proveedor, o haciendo ninguna statement sobre la calidad relativa de su producto, pero he visto que funciona en un escenario de gran volumen.

En general, diría que, si es posible, recomendaría evitar la integración directa a través de JNI si puede. Algunos enfoques de servicio REST simple o architecture basada en colas tenderán a ser más sencillos de desarrollar y diagnosticar. Puede obtener un rendimiento bastante decente si utiliza estas tecnologías desacopladas con cuidado.

A través de mi propia experiencia al intentar ejecutar un código Java desde Python ia de manera similar a como se ejecuta el código Python dentro del código Java en Python, no pude encontrar una metodología sencilla.

Mi solución a mi problema fue ejecutar este código java como scripts de beanshell llamando al intérprete beanshell como un comando shell desde mi código de python después de editar el código java en un archivo temporal con los paquetes y variables adecuados.

Si lo que estoy hablando es útil de alguna manera, me complace ayudarlo a compartir más detalles de mis soluciones.