Java与Python集成

58 投票
12 回答
88624 浏览
提问于 2025-04-15 12:52

我有一个Java应用程序,需要和一个第三方库结合使用。这个库是用Python写的,我对它没有任何控制权。我正在想办法找到最好的集成方式。我在尝试JEPP(Java嵌入式Python)——有没有人用过这个?我还有一个想法是使用JNI来和Python的C接口进行沟通。

如果有人对最好的实现方式有什么想法,我会很感激。谢谢。

12 个回答

21

很多年后,想再补充一个现在比较流行的选项……

如果你需要使用CPython的功能,py4j是个不错的选择。py4j在2016年到2020年这段时间更新频繁,逐渐变得受欢迎,因为像Apache Spark这样的项目就使用它来实现与CPython的互操作性

21

老实说,大多数直接在JVM中运行Python的方法都不太好用。要么不兼容(比如你用的第三方库的新版本可能用了Python 2.6的特性,但在Jython 2.5上就不行),要么就是比较“黑科技”(会出现难以理解的JVM错误信息,根本找不到解决办法)。

我更喜欢的方式是用RPC来整合这两者XML RPC在这里是个不错的选择,尤其是当你处理的数据量不大的时候。它的支持度很好——Python的标准库里就有这个功能,Java的库也很容易找到。根据你的具体情况,Java或Python的一方可以作为接收另一种语言连接的服务器。

还有一种不太常见但值得考虑的RPC替代方案是Google的协议缓冲(protobuf),它对优雅的RPC有2/3的支持。你只需要提供你的传输层。这并不需要太多工作,而且写起来也比较方便。

另一种选择是为你需要在Java中使用的Python功能写一个C的包装器,通过JVM的本地插件来使用它。你可以通过使用SWIG来简化这个过程,SWIG就是一个不错的工具。

基本上在你的情况下,流程是这样的:

  1. 为所有从Java到C++的调用创建一个SWIG接口。
  2. 编写C/C++代码来接收这些调用,并内部调用Python解释器,传入正确的参数。
  3. 将从Python得到的响应转换后,通过SWIG返回给你的Java代码。

这个解决方案相对复杂,在大多数情况下可能有点过于复杂。不过,如果你(出于某种原因)不能使用RPC的话,还是值得一试的。不过,我还是更推荐使用RPC。

38

为什么不使用 Jython 呢?我能想到的唯一缺点就是,如果你的库使用了CPython的本地扩展,那就可能有问题。

补充一下:如果你现在可以使用Jython,但担心将来可能会遇到库的问题,我建议你把这个库和你的应用程序分开(比如用某种适配器接口)。现在先用最简单的方法让它工作,然后再考虑使用JNI/CPython等,只有在真的需要的时候再去做。走JNI这条路会很麻烦,除非你真的没有其他选择。

撰写回答