我有一个需要与第三方库集成的Java应用程序。该库是用Python编写的,我对此没有任何发言权。我正试图找出与它集成的最佳方式。我正在尝试JEPP(Java嵌入式Python) - 以前有人用过吗?我的另一个想法是使用JNI与Python的C绑定进行通信。
任何关于最好的方法的想法将不胜感激。感谢。
答案 0 :(得分:35)
为什么不使用Jython?我可以立即想到的唯一缺点是你的库是否使用CPython原生扩展。
编辑:如果您现在可以使用Jython ,但认为您可能会遇到更高版本的库,我建议您尝试将库与您的应用程序隔离(例如某种适配器接口) )。选择目前最简单的方法,然后根据需要考虑JNI / CPython /等。除非你真的需要,否则去(痛苦的)JNI路线几乎无法获得。
答案 1 :(得分:17)
坦率地说以某种方式直接从JVM中运行Python的方法不起作用。它们要么不完全兼容(你的第三方库的新版本可以使用python 2.6特性而不能与Jython 2.5一起使用)或者hacky(它会破坏神秘的JVM堆栈跟踪而不是真正导致解决方案)。
我首选的方法是使用RPC 。如果你有适量的数据,XML RPC在这里不是一个糟糕的选择。它得到了很好的支持 - Python在其标准库中有它。 Java库也很容易找到。现在,根据您的设置,Java或Python部分将是接受其他语言连接的服务器。
一种不那么受欢迎但值得考虑的另一种做RPC的方法是Google protobuffers,它对nice rpc有2/3的支持。您只需提供传输层即可。没那么多的工作和写作的便利是合理的。
另一种选择是围绕那些需要向Java公开并通过JVM本机插件使用它的Python功能编写一个C包装器。您可以通过SWIG SWIG来缓解痛苦。
基本上在你的情况下,它的工作原理如下:
这个解决方案相当复杂,在大多数情况下有点过分。如果你(出于某种原因)无法负担RPC,那么值得做。但是RPC仍然是我的首选。
答案 2 :(得分:10)
多年以后,只是添加一个更受欢迎的选项......
如果您需要CPython功能,py4j是一个不错的选择。 py4j已经看到2017年 2016 的频繁更新并且已经获得了一些人气,因为它被用于例如由Apache Spark实现CPython interoperability。
答案 3 :(得分:7)
我的另一个想法是使用JNI与Python的C绑定进行通信。
我非常喜欢JNA:
JNA为Java程序提供了对本机共享库(Windows上的DLL)的轻松访问,而无需编写除Java代码之外的任何内容 - 不需要JNI或本机代码。此功能可与Windows的Platform / Invoke和Python的ctypes相媲美。访问在运行时是动态的,无需生成代码。
我的0.02美元:)
答案 4 :(得分:5)
您可以使用ActiveMQ之类的消息服务。它同时具有Python和Java支持。这样,您可以保留复杂的JNI或C绑定,并且只处理我认为简单的接口。此外,当库得到更新时,如果有的话,你不需要做太多改变。
答案 5 :(得分:4)
您是否考虑在Java VM上运行Jython?
答案 6 :(得分:4)
我已经研究过与JNI类似的设置。如果还没有看到它,这可能会有所帮助:
http://wiki.cacr.caltech.edu/danse/index.php/Communication_between_Java_and_Python
答案 7 :(得分:3)
如果你可以让你的Python代码在Jython中运行,那么你应该可以使用它来从Java调用它:
答案 8 :(得分:2)
最好的解决方案是使用Python程序抛出REST API。您定义服务并调用它们。您可能需要学习一些新模块。但是您会更灵活地进行期货更改。
下面列出了为此目的使用完整模块的一小部分: Python模块
Java模块(用于调用rest api) 球衣或Apache CXF
您将需要一条小的学习曲线,但是稍后您将获得更高的生产率和模块化甚至弹性...
答案 9 :(得分:1)