【问题标题】:py4J Error while obtaining a new communication channel on multithreaded java在多线程java上获取新的通信通道时出现py4J错误
【发布时间】:2018-06-15 15:40:42
【问题描述】:

我在将 py4J 与多线程 Java 应用程序一起使用时遇到问题。

我已经用 Python 实现了一个 Java 接口

class PythonListener(object):
    def __init__(self):
        pass
    def onNewMessage(self, message):
        print(message)
    class Java:
        implements = ["com.myMessaging.IListener"]

我从 Python 启动 JVM:

java_gateway = JavaGateway.launch_gateway(
                die_on_exit = True)

java_import(java_gateway.jvm, 'com.myMessaging.*')

// Start the multithread messaging server
myMessaging.Server.start()
// Register the listener
myMessaging.Server.registerListener(PythonListener())

myMessaging 是一个 Java 多线程应用程序。当消息到达时,某个线程会收到它并调用注册的Listeners的onNewMessage方法

事实上,当消息到达时,我得到了这个错误

py4j.Py4JException: Error while obtaining a new communication channel
    at py4j.CallbackClient.getConnectionLock(CallbackClient.java:257)
    at py4j.CallbackClient.sendCommand(CallbackClient.java:377)
    at py4j.CallbackClient.sendCommand(CallbackClient.java:356)
    at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.java:106)
    at com.sun.proxy.$Proxy79.onNewMessage(Unknown Source)
    at com.myMessaging.Server.notifyMessage(Server.java:235)
       ...Some stuff...
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
    at java.net.Socket.connect(Socket.java:478)
    at java.net.Socket.<init>(Socket.java:375)
    at java.net.Socket.<init>(Socket.java:218)
    at javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:212)
    at py4j.CallbackConnection.start(CallbackConnection.java:226)
    at py4j.CallbackClient.getConnection(CallbackClient.java:238)
    at py4j.CallbackClient.getConnectionLock(CallbackClient.java:250)
    ... 32 more

我认为这是因为有多个 Java 线程试图在同一个端口上连接到同一个 Python 实例,但是如何解决呢?我假设系统是多线程的,如here in the Py4J guide 所述。

会不会是接口实现中的错误? 感谢您的帮助!

【问题讨论】:

    标签: java python multithreading py4j


    【解决方案1】:

    当您使用 launch_gateway 时,负责执行 Python 回调的回调服务器不会启动。您必须明确启动它:

    java_gateway = JavaGateway.launch_gateway(die_on_exit = True)
    java_gateway.start_callback_server()
    # Your code here
    

    请注意,这将为 Python 回调使用默认端口,但您正在为 Java 调用使用临时端口。如果您想为 Java 和 Python 使用临时端口,the solution presented in the advanced topics section of Py4J is a bit more convoluted

    【讨论】:

    • 我担心使用标准端口,如果另一个应用程序想使用相同的端口怎么办?所以我可能会选择复杂的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2016-12-25
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多