J'ai une application Java qui doit s'intégrer à une bibliothèque tierce. La bibliothèque est écrite en Python, et je n'ai rien à dire à ce sujet. J'essaie de comprendre la J'essaie JEPP (Java Embedded Python) - quelqu'un l'a-t-il déjà utilisé? Mon autre idée est d'utiliser JNI pour communiquer avec les liaisons C pour Python.
Toute réflexion sur la meilleure façon de procéder serait appréciée. Merci.
Pourquoi ne pas utiliser Jython ? Le seul inconvénient auquel je peux penser immédiatement est que votre bibliothèque utilise des extensions natives CPython.
EDIT: Si vous pouvez utiliser Jython maintenant mais pensez que vous pourriez avoir des problèmes avec une version ultérieure de la bibliothèque, je vous suggère d'essayer d'isoler la bibliothèque de votre application (par exemple une sorte d'interface d'adaptateur). Optez pour la chose la plus simple qui fonctionne pour le moment, puis envisagez JNI/CPython/etc si et quand vous en avez besoin. Il n'y a pas grand-chose à gagner à emprunter la voie (douloureuse) JNI, sauf si vous y êtes vraiment obligé.
Franchement la plupart des façons d'exécuter en quelque sorte Python directement à partir de la JVM ne fonctionnent pas . Ils sont soit pas tout à fait- compatible (la nouvelle version de votre bibliothèque tierce peut utiliser les fonctionnalités python 2.6 et ne fonctionnera pas avec Jython 2.5) ou hacky (elle rompra avec le stacktrace JVM cryptique ne menant pas vraiment à la solution).
Ma façon préférée d'intégrer les deux utiliserait RPC . XML RPC n'est pas un mauvais choix ici, si vous avez des quantités modérées de données. Il est assez bien pris en charge - Python l'a dans sa bibliothèque standard. Java sont également faciles à trouver. Maintenant, selon votre configuration, soit Java ou Python serait un serveur acceptant la connexion d'une autre langue.
Un autre moyen moins populaire mais intéressant d'envisager de faire des RPC est les protobuffers de Google, qui ont 2/3 de support pour Nice rpc . Il vous suffit de fournir votre couche de transport. Pas beaucoup de travail et la commodité de l'écriture est raisonnable.
Une autre option consiste à écrire un wrapper C autour de ces éléments de fonctionnalité Python que vous devez exposer à Java et à l’utiliser via des plug-ins natifs JVM. Vous pouvez la douleur en allant avec SWIG SWIG .
Essentiellement, dans votre cas, cela fonctionne comme ça:
Cette solution est assez complexe, un peu exagérée dans la plupart des cas. Cela vaut quand même la peine si vous (pour une raison quelconque) ne pouvez pas vous permettre les RPC. Cependant, RPC serait toujours mon choix préféré.
De nombreuses années plus tard, juste pour ajouter une option qui est plus populaire de nos jours ...
Si vous avez besoin de la fonctionnalité CPython, py4j est une bonne option. py4j a vu des mises à jour fréquentes dans 20162017 2018 et a gagné en popularité, car il est utilisé par exemple par Apache Spark pour atteindre interopérabilité CPython .
Mon autre pensée est d'utiliser JNI pour communiquer avec les liaisons C pour Python.
J'aime beaucoup JNA :
JNA fournit Java programmes un accès facile aux bibliothèques partagées natives (DLL sur Windows) sans rien écrire sauf Java code — aucun JNI ou code natif n'est requis. Cette fonctionnalité est comparable à la plate-forme/Invoke de Windows et aux ctypes de Python. L'accès est dynamique à l'exécution sans génération de code.
Mon 0.02 $ :)
Vous pouvez utiliser un service de messagerie comme ActiveMQ . Il a à la fois Python et Java support. De cette façon, vous pouvez laisser les liaisons JNI ou C compliquées telles quelles et gérer uniquement ce que je considère comme une interface simple. De plus, lorsque la bibliothèque est mise à jour, vous n'avez pas besoin de changer grand-chose, le cas échéant.
Avez-vous envisagé d'exécuter Jython sur la machine virtuelle Java?
J'ai étudié une configuration similaire avec JNI. Peut-être que cela vous aidera si vous ne l'avez pas encore vu:
http://wiki.cacr.caltech.edu/danse/index.php/Communication_between_Java_and_Python
Si vous pouvez faire fonctionner votre code Python en Jython, vous devriez pouvoir l'utiliser pour l'appeler depuis Java: