¿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 compilar todas las llamadas posibles; Prefiero otra solución.
Escuché 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 se parece a lo que necesito. Sin embargo, la última versión es de enero de 2009 y veo personas que no compilan JPype.
¿JPype es un proyecto muerto?
¿Hay otras alternativas?
Saludos, David
Respuestas:
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 simple que JPype
He intentado Pyjnius / Jnius, JCC, javabridge, Jpype y Py4j.
Py4j es un poco difícil de usar, ya que necesita iniciar una puerta de enlace, agregando otra capa de fragilidad.
fuente
También puedes usar Py4J . Hay un ejemplo en la portada y mucha documentación, pero esencialmente, solo llama a los métodos Java desde su código python como si fueran métodos python:
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 funcionan 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, administrar la memoria, etc.)
Descargo de responsabilidad: soy el autor de Py4J
fuente
s = gateway.jvm.ch.ethz.ssh2.crypto.Base64() bt_out = s.decode();
aquí la clase Base64 tiene el método encode () y decode () y es parte del paquetech.ethz.ssh2.crypto
en mi archivo .jar. Obtengofrom py4j.reflection import MethodInvoker ImportError: No module named reflection
Pyjnius
Documentos: http://pyjnius.readthedocs.org/en/latest/
Github: https://github.com/kivy/pyjnius
Desde la página de github:
fuente
Estoy en OSX 10.10.2 y logré usar JPype.
Encontré problemas de instalación con Jnius ( otros también lo han hecho ), Javabridge instaló pero cometió errores misteriosos cuando traté de usarlo, PyJ4 tiene este inconveniente de tener que iniciar un servidor Gateway en Java primero, JCC no se 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 muy eficientemente las matrices java en matrices numpy (
np_arr = java_arr[:]
)El proceso de instalación fue:
Y deberías poder
import jpype
La siguiente demostración funcionó:
Cuando intenté llamar a mi propio código Java, primero tuve que compilar (
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 significaba cambiar el comando startJVM a:fuente
Si estás en Python 3, hay una bifurcación de JPype llamada JPype1-py3
Esto funciona para mí en OSX / Python 3.4.3. (Puede que necesite
export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version
)fuente
Últimamente he estado integrando muchas cosas en Python, incluido Java. El método más robusto que he encontrado es usar IKVM y un contenedor C #.
IKVM tiene una pequeña aplicación ordenada que le permite tomar cualquier JAR de Java y convertirlo directamente a .Net DLL. Simplemente traduce el bytecode de JVM a CLR bytecode. Ver http://sourceforge.net/p/ikvm/wiki/Ikvmc/ para más detalles.
La biblioteca convertida se comporta como una biblioteca nativa de C #, y puede usarla sin necesidad de JVM. A continuación, puede crear un proyecto de contenedor de DLL C # y agregar una referencia a la DLL convertida.
Ahora puede crear algunos apéndices de envoltura que llaman a los métodos que desea exponer y marcar esos métodos como DllEport. Ver https://stackoverflow.com/a/29854281/1977538 para más detalles.
La DLL de contenedor actúa como una biblioteca C nativa, con los métodos exportados como los métodos C exportados. Puede conectarse a ellos utilizando ctype como de costumbre.
Lo probé con Python 2.7, pero también debería funcionar con 3.0. Funciona en Windows y Linux.
Si utiliza C #, este es probablemente el mejor enfoque para intentar integrar casi cualquier cosa en Python.
fuente
Estoy empezando a usar JPype 0.5.4.2 (julio de 2011) y parece que funciona bien ...
Estoy en Xubuntu 10.04
fuente
Supongo que si puede pasar de C ++ a Java, ya está todo listo. He visto que un producto del tipo que mencionas funciona bien. Resulta que el que usamos fue CodeMesh . No estoy respaldando específicamente a este proveedor, ni estoy haciendo ninguna declaración sobre la calidad relativa de su producto, pero lo he visto funcionar en un escenario de gran volumen.
En general, diría que, si es posible, recomendaría mantenerse alejado de la integración directa a través de JNI si puede. Algún enfoque de servicio REST simple o arquitectura basada en colas tenderá a ser más simple de desarrollar y diagnosticar. Puede obtener un rendimiento bastante decente si utiliza estas tecnologías desacopladas con cuidado.
fuente
A través de mi propia experiencia tratando de ejecutar algún código Java desde Python, de manera similar a cómo 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 de beanshell como un comando de shell desde mi código python después de editar el código java en un archivo temporal con los paquetes y variables apropiados.
Si de lo que estoy hablando es útil de alguna manera, me complace ayudarlo a compartir más detalles de mis soluciones.
fuente