Java Python 集成

Posted

技术标签:

【中文标题】Java Python 集成【英文标题】:Java Python Integration 【发布时间】:2010-11-10 07:40:57 【问题描述】:

我有一个需要与第 3 方库集成的 Java 应用程序。该库是用 Python 编写的,对此我没有任何发言权。我正在尝试找出与之集成的最佳方式。我正在尝试 JEPP(Java Embedded Python)——以前有人用过吗?我的另一个想法是使用 JNI 与 Python 的 C 绑定进行通信。

任何关于最佳方式的想法都将不胜感激。谢谢。

【问题讨论】:

如果python库都是纯python写的,那用Jython呢? 【参考方案1】:

您是否考虑过在 Java VM 上运行 Jython?

【讨论】:

IronPython 用于 .NET,而不是 Java。 IKVM 可以将这三个潜在地结合起来,但是 ick :) 我是否错过了其他地方对 IronPython 的引用? 是的 - 在 Cletus 编辑之前的回答中。 (编辑不显示,因为它是在最初的几分钟内。)【参考方案2】:

为什么不使用Jython?我能立即想到的唯一缺点是您的库是否使用 CPython 原生扩展。

编辑:如果您现在可以使用 Jython,但认为您可能在使用更高版本的库时遇到问题,我建议您尝试将库与您的应用程序隔离(例如某种适配器接口)。使用目前最简单的方法,然后在需要时考虑 JNI/CPython/etc。除非你真的必须这样做,否则走(痛苦的)JNI 路线几乎没有什么好处。

【讨论】:

我查看了 Jython 库。问题是我不能保证我使用的库不会(或将来不会)使用本机扩展。 我会这样做的。谢谢。我是否需要向 py 文件添加任何特殊内容才能使用 Jython 运行它?或者如果它是原生 python,它应该运行吗? 我对 Jython 没有太多经验 - 请参阅文档 :) 会做的,感谢帮助。【参考方案3】:

如果您可以让您的 Python 代码在 Jython 中运行,那么您应该能够使用它从 Java 中调用它:

http://jython.sourceforge.net/cgi-bin/faqw.py?req=show&file=faq06.001.htp

【讨论】:

【参考方案4】:

我用 JNI 研究了类似的设置。如果还没有看到,也许这会有所帮助:

http://wiki.cacr.caltech.edu/danse/index.php/Communication_between_Java_and_Python

http://jpe.sourceforge.net/

【讨论】:

【参考方案5】:

您可以使用ActiveMQ 之类的消息服务。它同时支持Python 和Java。这样,您可以保留复杂的 JNI 或 C 绑定,只处理我认为的简单接口。此外,当库更新时,您无需进行太多更改(如果有的话)。

【讨论】:

【参考方案6】:

坦率地说大多数直接从 JVM 中运行 Python 的方法都行不通。它们要么不太兼容(您的第三方库的新版本可以使用 python 2.6 功能,并且不能与 Jython 2.5 一起使用),要么是 hacky(它会破坏神秘的 JVM 堆栈跟踪,并没有真正导致解决方案)。

我更喜欢将两者集成的方式是使用 RPC。如果您的数据量适中,XML RPC 在这里是个不错的选择。它得到了很好的支持——Python 的标准库中有它。 Java 库也很容易找到。现在根据您的设置,Java 或 Python 部分将成为接受其他语言连接的服务器。

一种不太流行但值得考虑的替代方法是 Google protobuffers,它对 nice rpc 有 2/3 的支持。您只需要提供您的传输层。没有那么多的工作和写作的便利是合理的。

另一种选择是围绕需要向 Java 公开的 Python 功能编写 C 包装器,并通过 JVM 原生插件使用它。您可以使用 SWIG SWIG 来减轻痛苦。

在你的情况下,它基本上是这样工作的:

    为从 Java 到 C++ 的所有方法调用创建一个 SWIG 接口。 创建将接收您的调用并在内部调用具有正确参数的 python 解释器的 C/C++ 代码。 转换您从 python 获得的响应并通过 swig 将其发送回您的 Java 代码。

这个解决方案相当复杂,在大多数情况下有点矫枉过正。如果您(出于某种原因)买不起 RPC,仍然值得这样做。不过,RPC 仍然是我的首选。

【讨论】:

这种非JVM兼容性是Python最大的缺点。这就是我们决定使用 Scala 的原因。它甚至更好。 Marcin,出于性能和可扩展性的原因,大数据实现(算法或应用程序)不希望使用远程调用方式。确实“不完全兼容”是一个问题,但“打破神秘的 JVM 堆栈跟踪”需要一些解释和示例。您的意思是难以调试或无法运行?我正在尝试在进程中执行 JNI 的 Jep,这似乎是最好的选择。 github.com/mrj0/jep/wiki/How-Jep-Works。想法?【参考方案7】:

我的另一个想法是使用 JNI 与 Python 的 C 绑定进行通信。

我很喜欢JNA:

JNA 使 Java 程序可以轻松访问本地共享库(Windows 上的 DLL),而无需编写 Java 代码以外的任何内容——不需要 JNI 或本地代码。此功能可与 Windows 的 Platform/Invoke 和 Python 的 ctypes 相媲美。访问在运行时是动态的,无需代码生成。

我的 0.02 美元 :)

【讨论】:

【参考方案8】:

多年后,只是为了添加一个现在更流行的选项......

如果您需要 CPython 功能,py4j 是一个不错的选择。 py4j 在 2016 2017 2018 2019 2020 年看到了频繁的更新,并获得了一些人气,因为它被使用例如通过 Apache Spark 实现CPython interoperability。

【讨论】:

确实是比 Jython 更好的选择,Jython 是一个技术死胡同,似乎不再维护了。 py4j 的第一个发布版本是在 2009 年。在撰写本文时,最后一个发布版本是在 2018 年 10 月。【参考方案9】:

最好的解决方案,是使用 Python 程序抛出 REST API。您定义您的服务并调用它们。您可能需要学习一些新模块。但是您会更加灵活地应对未来的变化。

这里有一个用于此目的的完整模块的小列表: Python 模块

烧瓶 Flask-SQLAlchemy Flask-Restful SQLite3 Jsonify

Java 模块(用于调用 rest api) Jersey 或 Apache CXF

您将需要一个小的学习曲线,但稍后您将获得更高的生产力和模块化甚至弹性...

【讨论】:

【参考方案10】:

这些工具可以更轻松地弥合 Python 和 Java 之间的差距:

1.Jython 用 Java 实现的 Python

2.JPype 允许 Python 运行 java 命令

3.Jepp Java 嵌入式 Python

4.JCC 用于从 C++/Python 调用 Java 的 C++ 代码生成器

5.Javabridge 一个用于从 CPython 运行和与 JVM 交互的包

6.py4j 允许 Python 运行 java 命令。

7.voc BeeWare 套件的一部分。将 python 代码转换为 Java 字节码。

8.p2j 将 Python 代码转换为 Java。不再开发。

【讨论】:

我已经用这些信息更新了alternatives guide for JPype。 还有GraalPython【参考方案11】:

我也认为 在 Java 中运行命令行 不会是不好的做法 (*** question here)。 可能通过某些数据库共享数据。

我喜欢通过 bash 管道 连接两个应用程序的方式,但我没有这方面的实践,所以我想知道在 python/java 上编写逻辑来处理这个问题有多困难侧面。

或者其他有效的方法是使用支持过程编程的远程过程调用 (RPC)。使用 RPC,您可以调用共享环境中的方法。例如,您可以使用 RPC 从本地计算机调用远程计算机中的函数。我们可以将 RPC 定义为分布式系统中的一种通信类型。 (Marcin 上面提到过)

或者,非常幼稚的方式是通过通用文件进行通信。但为了简单和快速,我的投票是使用共享数据库 x rest API x socket通信

我也喜欢 Marcin 所写的 XML RPC

我想建议避免在 JVM 或 C++ 绑定下运行 Python 的任何复杂性。最好使用当今的趋势,这些趋势显然是网络技术。

作为共享数据库,MongoDB 可能是一个很好的解决方案,或者甚至更好的 Redis 作为内存数据库

【讨论】:

以上是关于Java Python 集成的主要内容,如果未能解决你的问题,请参考以下文章

android python 完全集成

python_jenkins_集成

Corba python 与 web 服务 java 的集成

如何用python写一个脚本,来跑java代码上的cucumber集成测试

性能调优Python集成Java的服务OOM问题分析经历

python_java_selenium_ jenkins持续集成Firfox_chrome浏览器不显示的解决方法?