从 Python 调用 Java

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3652554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 03:12:15  来源:igfitidea点击:

Calling Java from Python

javapython

提问by David Portabella

What is the best way to call java from python? (jython and RPC are not an option for me).

从python调用java的最佳方法是什么?(jython 和 RPC 不是我的选择)。

I've heard of JCC: http://pypi.python.org/pypi/JCC/1.9a C++ code generator for calling Java from C++/Python But this requires compiling every possible call; I would prefer another solution.

我听说过 JCC:http: //pypi.python.org/pypi/JCC/1.9一个 C++ 代码生成器,用于从 C++/Python 调用 Java 但这需要编译每个可能的调用;我更喜欢另一种解决方案。

I've hear about JPype: http://jpype.sourceforge.net/tutorial: http://www.slideshare.net/onyame/mixing-python-and-java

我听说过 JPype:http: //jpype.sourceforge.net/教程: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() 

This looks like what I need. However, the last release is from Jan 2009 and I see people failing to compile JPype.

这看起来像我需要的。但是,最后一个版本是 2009 年 1 月,我看到人们无法编译 JPype。

Is JPype a dead project?

JPype 是一个死项目吗?

Are there any other alternatives?

还有其他选择吗?

Regards, David

问候, 大卫

采纳答案by Jie Bao

Here is my summary of this problem: 5 Ways of Calling Java from Python

这是我对这个问题的总结:5 Ways of Calling Java from Python

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

http://baojie.org/blog/2014/06/16/call-java-from-python/缓存

Short answer: Jpype works pretty well and is proven in many projects (such as python-boilerpipe), but Pyjnius is faster and simpler than JPype

简短回答:Jpype 工作得很好,并在许多项目(例如 python-boilerpipe)中得到证明,但 Pyjnius 比 JPype 更快更简单

I have tried Pyjnius/Jnius, JCC, javabridge, Jpype and Py4j.

我尝试过 Pyjnius/Jnius、JCC、javabridge、Jpype 和 Py4j。

Py4j is a bit hard to use, as you need to start a gateway, adding another layer of fragility.

Py4j 有点难用,因为你需要启动一个网关,增加了另一层脆弱性。

回答by djna

I'm assuming that if you can get from C++ to Java then you are all set. I've seen a product of the kind you mention work well. As it happens the one we used was CodeMesh. I'm not specifically endorsing this vendor, or making any statement about their product's relative quality, but I have seen it work in quite a high volume scenario.

我假设如果您可以从 C++ 转到 Java,那么您就万事大吉了。我见过你提到的那种产品效果很好。碰巧我们使用的是CodeMesh。我并没有特别认可这家供应商,也没有对他们产品的相对质量发表任何声明,但我已经看到它在相当大的容量情况下工作。

I would say generally that if at all possible I would recommend keeping away from direct integration via JNI if you can. Some simple REST service approach, or queue-based architecture will tend to be simpler to develop and diagnose. You can get quite decent perfomance if you use such decoupled technologies carefully.

我一般会说,如果可能的话,我建议尽可能避免通过 JNI 直接集成。一些简单的 REST 服务方法或基于队列的架构往往更易于开发和诊断。如果您仔细使用这种解耦技术,您可以获得相当不错的性能。

回答by shady alaa

Through my own experience trying to run some java code from within python i a manner similar to how python code runs within java code in python, I was unable to a find a straight forward methodology.

根据我自己尝试从 python ia 中运行一些 java 代码的经验,类似于 python 代码在 python 中的 java 代码中运行的方式,我无法找到一种直接的方法。

My solution to my problem was by running this java code as beanshell scripts by calling the beanshell interpreter as a shell commnad from within my python code after editing the java code in a temporary file with the appropriate packages and variables.

我对我的问题的解决方案是通过在使用适当的包和变量的临时文件中编辑 java 代码后,通过在我的 python 代码中调用 beanshell 解释器作为 shell commnad 将此 java 代码作为 beanshell 脚本运行。

If what I am talking about is helpful in any manner, I am glad to help you sharing more details of my solutions.

如果我所说的有任何帮助,我很乐意帮助您分享我的解决方案的更多细节。

回答by Barthelemy

You could also use Py4J. There is an example on the frontpage and lots of documentation, but essentially, you just call Java methods from your python code as if they were python methods:

您也可以使用Py4J。首页上有一个示例和大量文档,但本质上,您只需从 python 代码中调用 Java 方法,就好像它们是 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

As opposed to Jython, one part of Py4J runs in the Python VM so it is always "up to date" with the latest version of Python and you can use libraries that do not run well on Jython (e.g., lxml). The other part runs in the Java VM you want to call.

与 Jython 不同,Py4J 的一部分在 Python VM 中运行,因此它始终与最新版本的 Python 保持“同步”,您可以使用在 Jython 上运行不佳的库(例如,lxml)。另一部分在您要调用的 Java VM 中运行。

The communication is done through sockets instead of JNI and Py4J has its own protocol (to optimize certain cases, to manage memory, etc.)

通信是通过套接字而不是 JNI 完成的,Py4J 有自己的协议(优化某些情况,管理内存等)

Disclaimer: I am the author of Py4J

免责声明:我是 Py4J 的作者

回答by Joril

I'm just beginning to use JPype 0.5.4.2 (july 2011) and it looks like it's working nicely...
I'm on Xubuntu 10.04

我刚刚开始使用 JPype 0.5.4.2(2011 年 7 月),它看起来运行良好......
我在 Xubuntu 10.04

回答by gdw2

Pyjnius.

皮尼乌斯。

Docs: http://pyjnius.readthedocs.org/en/latest/

文档:http: //pyjnius.readthedocs.org/en/latest/

Github: https://github.com/kivy/pyjnius

Github:https: //github.com/kivy/pyjnius

From the github page:

从github页面:

A Python module to access Java classes as Python classes using JNI.

PyJNIus is a "Work In Progress".

Quick overview

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

使用 JNI 将 Java 类作为 Python 类访问的 Python 模块。

PyJNIus 是一个“进行中的工作”。

快速概览

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

回答by k107

If you're in Python 3, there's a fork of JPype called JPype1-py3

如果您使用的是 Python 3,则有一个名为JPype1-py3 的 JPype 分支

pip install JPype1-py3

This works for me on OSX / Python 3.4.3. (You may need to export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version)

这在 OSX / Python 3.4.3 上对我有用。(你可能需要export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version

from jpype import *
startJVM(getDefaultJVMPath(), "-ea")
java.lang.System.out.println("hello world")
shutdownJVM()

回答by Rob Deary

I've been integrating a lot of stuff into Python lately, including Java. The most robust method I've found is to use IKVM and a C# wrapper.

最近我一直在将很多东西集成到 Python 中,包括 Java。我发现的最可靠的方法是使用 IKVM 和 C# 包装器。

IKVM has a neat little application that allows you to take any Java JAR, and convert it directly to .Net DLL. It simply translates the JVM bytecode to CLR bytecode. See http://sourceforge.net/p/ikvm/wiki/Ikvmc/for details.

IKVM 有一个简洁的小应用程序,它允许您获取任何 Java JAR,并将其直接转换为 .Net DLL。它只是将 JVM 字节码转换为 CLR 字节码。有关详细信息,请参阅http://sourceforge.net/p/ikvm/wiki/Ikvmc/

The converted library behaves just like a native C# library, and you can use it without needing the JVM. You can then create a C# DLL wrapper project, and add a reference to the converted DLL.

转换后的库就像本机 C# 库一样,您可以在不需要 JVM 的情况下使用它。然后,您可以创建一个 C# DLL 包装器项目,并添加对转换后的 DLL 的引用。

You can now create some wrapper stubs that call the methods that you want to expose, and mark those methods as DllEport. See https://stackoverflow.com/a/29854281/1977538for details.

您现在可以创建一些包装存根来调用您想要公开的方法,并将这些方法标记为 DllEport。有关详细信息,请参阅https://stackoverflow.com/a/29854281/1977538

The wrapper DLL acts just like a native C library, with the exported methods looking just like exported C methods. You can connect to them using ctype as usual.

包装器 DLL 的行为就像一个本地 C 库,导出的方法看起来就像导出的 C 方法。您可以像往常一样使用 ctype 连接到它们。

I've tried it with Python 2.7, but it should work with 3.0 as well. Works on Windows and the Linuxes

我已经用 Python 2.7 试过了,但它也应该适用于 3.0。适用于 Windows 和 Linuxes

If you happen to use C#, then this is probably the best approach to try when integrating almost anything into python.

如果您碰巧使用 C#,那么这可能是将几乎所有内容集成到 Python 时尝试的最佳方法。

回答by Peter

I'm on OSX 10.10.2, and succeeded in using JPype.

我在 OSX 10.10.2 上,并成功使用了 JPype。

Ran into installation problems with Jnius (others have too), Javabridge installed but gave mysterious errors when I tried to use it, PyJ4 has this inconvenience of having to start a Gateway server in Java first, JCC wouldn't install. Finally, JPype ended up working. There's a maintained fork of JPypeon Github. It has the major advantages that (a) it installs properly and (b) it can very efficiently convert java arrays to numpy array (np_arr = java_arr[:])

遇到了 Jnius 的安装问题(其他人也遇到),Javabridge 安装了但是当我尝试使用它时出现了神秘的错误,PyJ4 有这种不便,必须先用 Java 启动网关服务器,JCC 不会安装。最后,JPype 终于可以工作了。在 Github 上有一个JPype维护分支。它的主要优点是 (a) 安装正确 (b) 可以非常有效地将 java 数组转换为 numpy 数组 ( np_arr = java_arr[:])

The installation process was:

安装过程是:

git clone https://github.com/originell/jpype.git
cd jpype
python setup.py install

And you should be able to import jpype

你应该能够 import jpype

The following demo worked:

以下演示有效:

import jpype as jp
jp.startJVM(jp.getDefaultJVMPath(), "-ea")
jp.java.lang.System.out.println("hello world")
jp.shutdownJVM() 

When I tried calling my own java code, I had to first compile (javac ./blah/HelloWorldJPype.java), and I had to change the JVM path from the default (otherwise you'll get inexplicable "class not found" errors). For me, this meant changing the startJVM command to:

当我尝试调用自己的 java 代码时,我必须首先编译 ( javac ./blah/HelloWorldJPype.java),并且必须更改默认的 JVM 路径(否则您会得到莫名其妙的“找不到类”错误)。对我来说,这意味着将 startJVM 命令更改为:

jp.startJVM('/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/MacOS/libjli.dylib', "-ea")
c = jp.JClass('blah.HelloWorldJPype')  
# Where my java class file is in ./blah/HelloWorldJPype.class
...