133 votes

Appeler Java depuis Python

Quelle est la meilleure façon 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 depuis C++/Python Mais cela nécessite de compiler chaque appel possible ; 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 personnes qui ne parviennent pas à compiler JPype.

JPype est-il un projet mort ?

Existe-t-il d'autres alternatives ?

Regards, David

3 votes

Pourriez-vous expliquer pourquoi vous pensez que Jython et RPC ne sont pas une option pour votre situation ?

2 votes

Il semble qu'entre-temps, il y ait eu une nouvelle version de JPype : 0.5.4.2 le 2011-07-28

142voto

Barthelemy Points 1976

Vous pouvez également utiliser Py4J . Il y a un exemple sur la page d'accueil et beaucoup de documentation, mais essentiellement, vous appelez les méthodes Java depuis votre code python comme s'il s'agissait de méthodes 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 la VM Python, de sorte qu'elle est toujours "à jour" avec la dernière version de Python et que vous pouvez utiliser des bibliothèques qui ne fonctionnent pas bien sur Jython (par exemple, lxml). L'autre partie s'exécute dans la VM Java que vous voulez appeler.

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

Disclaimer : Je suis l'auteur de Py4J

0 votes

Merci pour le lien. Cela ressemble à une alternative open-source à ce que djna a proposé, CodeMesh. Je vais définitivement y jeter un coup d'oeil. Cependant, il y a le même problème que dans CodeMesh, il faut démarrer le processus Java avant, et s'assurer qu'il fonctionne avant d'utiliser python (voir l'exemple dans la page principale du projet, ListPrinter.java -> main -> GatewayServer.start()). C'est un point d'échec possible. Je continue à penser que l'approche de JPype est excellente ; seulement, il semble que ce soit un projet mort.

8 votes

@alvas Je maintiens toujours Py4J si c'est ce que vous vouliez dire.

0 votes

@Barthelemy, comment procéder à l'intégration si le code Java dépend d'une bibliothèque - opencv dans mon cas ?

54voto

Jie Bao Points 66

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

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

Réponse courte : Jpype fonctionne assez bien et a fait ses preuves dans de nombreux projets (comme 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 autre couche de fragilité.

20voto

gdw2 Points 1318

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 classes Python en utilisant JNI.

PyJNIus est un "travail en cours".

Aperçu rapide

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

3voto

Joril Points 5296

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

2voto

djna Points 34761

Je suppose que si vous pouvez passer de C++ à Java, vous êtes prêt. J'ai vu un produit du type de celui que vous mentionnez fonctionner correctement. Il se trouve que celui que nous avons utilisé était CodeMesh . Je ne recommande pas spécifiquement ce fournisseur, ni ne fais de déclaration sur la qualité relative de son produit, mais je l'ai vu fonctionner dans un scénario de volume assez élevé.

D'une manière générale, je dirais que, dans la mesure du possible, je vous recommande d'éviter l'intégration directe via JNI si vous le pouvez. Une simple approche de service 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 tout à fait décentes si vous utilisez ces technologies découplées avec soin.

0 votes

RPC (ou REST) n'est pas une option pour moi.

0 votes

Cela nécessiterait de démarrer le processus Java avant, et de s'assurer qu'il est en cours d'exécution avant d'utiliser python. C'est un point d'échec possible. L'approche de JPype est excellente ; seulement, il semble que ce soit un projet mort.

0 votes

Je ne fais que donner des conseils généraux. JNI est un champ de mines potentiel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X