web-dev-qa-db-fra.com

Appeler Java de Python

Quel est le meilleur moyen d'appeler Java depuis python? (Jython et RPC ne sont pas une option pour moi).

J'ai entendu parler de JCC: http://pypi.python.org/pypi/JCC/1.9 un générateur de code C++ pour appeler Java à partir de C++/Python Mais cela nécessite la compilation de tous les appels possibles, je préférerais une autre solution.

J'ai entendu parler de JPype: http://jpype.sourceforge.net/ tutoriel: 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() 

Cela ressemble à ce dont j'ai besoin. Cependant, la dernière version date de janvier 2009 et je vois des gens ne pas compiler JPype.

JPype est-il un projet mort?

Y a-t-il d'autres alternatives?

Cordialement, David

114
David Portabella

Voici mon résumé de ce problème: 5 façons d’appeler Java de Python

http://baojie.org/blog/2014/06/16/call-Java-from-python/ ( mis en cache )

Réponse courte: Jpype fonctionne assez bien et a fait ses preuves dans de nombreux projets (tels que python-boilerpipe), mais Pyjnius est plus rapide et plus simple que JPype.

J'ai essayé Pyjnius/Jnius, JCC, javabridge, Jpype et Py4j.

Py4j est un peu difficile à utiliser, car vous devez démarrer une passerelle, ce qui ajoute une couche de fragilité.

42
Jie Bao

Vous pouvez également utiliser Py4J . Il y a un exemple sur la page d'accueil et beaucoup de documentation, mais vous devez simplement appeler Java à partir de votre code python comme si elles étaient 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

Contrairement à Jython, une partie de Py4J s’exécute dans le Python VM) de sorte qu’il est toujours "à jour" avec la dernière version de Python et vous pouvez utiliser des bibliothèques qui ne fonctionnent pas bien sur Jython (par exemple, lxml). L’autre partie s’exécute dans le Java VM vous voulez appeler.

La communication se fait par des sockets au lieu de JNI et Py4J a son propre protocole (pour optimiser certains cas, pour gérer la mémoire, etc.)

Disclaimer: Je suis l'auteur de Py4J

127
Barthelemy

Pyjnius.

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

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

De la page github:

Un module Python pour accéder aux classes Java en tant que Python utilisant JNI.

PyJNIus est un "travail en cours".

Rapide vue d'ensemble

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

Je suis sur OSX 10.10.2 et j'ai réussi à utiliser JPype.

Rencontré des problèmes d’installation avec Jnius ( d’autres ont aussi ), Javabridge est installé mais a donné de mystérieuses erreurs lorsque j’ai essayé de l’utiliser, PyJ4 a le désagrément de devoir démarrer un serveur de passerelle dans Java d’abord, JCC n’installe pas. Enfin, JPype a fini par fonctionner. Il y a un fork maintenu de JPype sur Github. Il présente les principaux avantages que (a) il s’installe correctement et (b ) il peut très efficacement convertir Java les tableaux en tableau numpy (np_arr = Java_arr[:])

Le processus d'installation était:

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

Et vous devriez être capable de import jpype

La démo suivante a fonctionné:

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

Quand j'ai essayé d'appeler mon propre code Java, je devais d'abord compiler (javac ./blah/HelloWorldJPype.Java)) Et je devais changer le chemin d'accès de la machine virtuelle par défaut (sinon, vous obtiendrez inexplicable "class not found" erreurs). Pour moi, cela signifiait changer la commande startJVM en:

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
Peter

Si vous êtes dans Python 3, il existe un fork de JPype appelé JPype1-py

pip install JPype1-py3

Cela fonctionne pour moi sur OSX/Python 3.4.3. (Vous aurez peut-être besoin de export Java_HOME=/Library/Java/JavaVirtualMachines/your-Java-version)

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

J'ai récemment intégré beaucoup de choses dans Python, y compris Java. La méthode la plus robuste que j'ai trouvée consiste à utiliser IKVM et un wrapper C #.

IKVM a une petite application soignée qui vous permet de prendre n'importe quel fichier JAR Java) et de le convertir directement en DLL .Net. Il traduit simplement le bytecode de la JVM en bytecode CLR. Voir http://sourceforge.net/p/ikvm/wiki/Ikvmc/ pour plus de détails.

La bibliothèque convertie se comporte comme une bibliothèque C # native et vous pouvez l'utiliser sans avoir besoin de la machine virtuelle Java. Vous pouvez ensuite créer un projet wrapper C # DLL) et ajouter une référence à la DLL convertie.

Vous pouvez maintenant créer des talons d'encapsuleur qui appellent les méthodes que vous souhaitez exposer et les marquer comme DllEport. Voir https://stackoverflow.com/a/29854281/1977538 pour plus de détails.

Le wrapper DLL agit comme une bibliothèque C native, les méthodes exportées ressemblant aux méthodes C exportées. Vous pouvez vous y connecter en utilisant ctype comme d'habitude.

Je l'ai essayé avec Python 2.7, mais il devrait également fonctionner avec la version 3.0. Fonctionne sous Windows et les systèmes Linux

Si vous utilisez C #, il s’agit probablement de la meilleure approche lors de l’intégration de presque tout dans python.

2
Rob Deary

Je commence tout juste à utiliser JPype 0.5.4.2 (juillet 2011) et il semble que cela fonctionne bien ...
Je suis sur Xubuntu 10.04

2
Joril

Je suppose que si vous pouvez obtenir du C++ à Java, alors vous êtes tous ensemble. J'ai vu un produit du type que vous avez mentionné qui fonctionne bien. En l'occurrence, celui que nous avons utilisé était CodeMesh . Je n'approuve pas spécifiquement ce fournisseur, ni ne fais aucune déclaration sur la qualité relative de son produit, mais je l'ai vu fonctionner dans un scénario de volume assez élevé.

De manière générale, je dirais que si possible, je vous conseillerais de vous abstenir de toute intégration directe via JNI. Une approche de service simple REST) ou une architecture basée sur les files d'attente aura tendance à être plus simple à développer et à diagnostiquer. Vous pouvez obtenir des performances assez convenables si vous utilisez ces technologies découplées avec précaution.

1
djna

Par ma propre expérience d’essayer d’exécuter du code Java à partir de python de manière similaire à la façon dont python est exécuté dans = Java code en python, j’ai été incapable de trouver une méthodologie simple.

Ma solution à mon problème consistait à exécuter ce code Java en tant que scripts beanshell en appelant l'interpréteur beanshell en tant que commnad Shell à partir de mon python après avoir modifié le = Java code dans un fichier temporaire avec les packages et les variables appropriés.

Si ce dont je parle est utile de quelque manière que ce soit, je suis heureux de vous aider à partager davantage de détails sur mes solutions.

0
shady alaa