py4j:如何从 Python 启动 java 网关

Posted

技术标签:

【中文标题】py4j:如何从 Python 启动 java 网关【英文标题】:py4j: how to launch the java Gateway from Python 【发布时间】:2017-08-07 03:55:35 【问题描述】:

我可以在 Python 中与我的示例 Java 程序进行交互,方法是打开我的 Java 程序,然后使用以下 Python 代码:

from py4j.java_gateway import JavaGateway
gg = JavaGateway()
sw = gg.entry_point.getInstance()
sw.run()
...

但是,这样做的缺点是我必须在使用此代码之前以某种方式打开 Java 程序。

我发现有一个名为launch_gateway的方法似乎很方便实现这个目标。

py4j.java_gateway.launch_gateway(jarpath="path_to_my_jar.jar")

但是,如果以这种方式启动,我将无法连接到我的 Java 程序。

我尝试使用以下代码:

port = py4j.java_gateway.launch_gateway(jarpath="path_to_my_jar.jar")
gp = GatewayParameters(port=port) 
gg = JavaGateway(gateway_parameters=gp)
sw = gg.entry_point.getInstance()

但我收到以下错误:

An error occurred while calling t.getInstance. Trace:
py4j.Py4JException: Target Object ID does not exist for this gateway :t

我想我尝试连接到网关的方式有问题。

有什么建议吗?

谢谢

【问题讨论】:

【参考方案1】:

巴泰勒米,你是对的!我最初误解了它的工作原理。

launch_gateway 在 py4j.jar 中运行网关,这对于与标准 JVM 交互很有用,但显然不包含自定义代码。

但是,正如您所建议的,classpath 参数允许您加载其他自定义 Java 代码。

这是一个“最小的例子”:

from py4j.java_gateway import JavaGateway 
gg = JavaGateway.launch_gateway(classpath="/path/my_jar.jar")

myclass_instance = gg.jvm.my_class_package_name.MyClass()
result = myclass_instance.my_method()

请注意,my_jar.jar 不必启动网关。

launch_gateway 为您提供了不错的功能,例如:die_on_exit、stdout/stdin 重定向和自动端口选择。

【讨论】:

【参考方案2】:

我看到了两个潜在的问题:

    jarpath 应该是 Py4J 的 jar 的路径。您可以在 launch_gateway 的类路径参数中添加您的库。 当你从 launch_gateway 启动一个 py4j.GatewayServer 时,没有指定入口点,所以 entry_point 确实如此

【讨论】:

以上是关于py4j:如何从 Python 启动 java 网关的主要内容,如果未能解决你的问题,请参考以下文章

py4j - 我将如何在 java 中调用 python 方法

如何停止 Python 运行 Py4J ClientServer

使用 py4j 将矩阵作为 int[][] 数组从 Python 发送到 Java

Py4J 的开销比 Jython 和 JPype 大

如何在 py4j 中将 Java 列表转换为 Python 列表

Java 数组到 NumPy 数组的快速转换 (Py4J)