How to call a Java method that takes an object as argument?

16 views
Skip to first unread message

Morpheus

unread,
Aug 29, 2023, 9:05:01 PM8/29/23
to Py4J Support and Comments
Hello,

I have a method in my Java entrypoint class like this

foo(SomeInterface obj)

where SomeInterface is a Java interface.

I have implemented the interface in Python like so e.g.:

class MyImplementation:

    ...
     class Java:
           implements = ["a.b.c.d.SomeInterface"]

when I try to call the Java method from Python like so:

gateway = JavaGateway()
py4j = gateway.entry_point.create(100, 16, 100, "l2")
py4j_obj.foo(x)

where x is of type MyImplementation I get this error:

raise Py4JJavaError(
py4j.protocol.Py4JJavaError: An error occurred while calling o10.add.
: java.net.ConnectException: Connection refused
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:580)
at java.base/sun.nio.ch.Net.connect(Net.java:569)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:576)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:666)
at java.base/java.net.Socket.connect(Socket.java:600)
at java.base/java.net.Socket.<init>(Socket.java:509)
at java.base/java.net.Socket.<init>(Socket.java:321)
at java.base/javax.net.DefaultSocketFactory.createSocket(SocketFactory.java:273)
at py4j.CallbackConnection.start(CallbackConnection.java:226)
at py4j.CallbackClient.getConnection(CallbackClient.java:238)
at py4j.CallbackClient.getConnectionLock(CallbackClient.java:250)
at py4j.CallbackClient.sendCommand(CallbackClient.java:377)
at py4j.CallbackClient.sendCommand(CallbackClient.java:356)
at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.java:106)
at jdk.proxy4/jdk.proxy4.$Proxy31.dimensions(Unknown Source)
at a.b.c.d.foo(App.java:265)

How can I fix this? Thanks.

Morpheus

unread,
Aug 29, 2023, 9:14:45 PM8/29/23
to Py4J Support and Comments, Morpheus
nevermind. found the answer here: https://stackoverflow.com/a/14455834/147530. i wasn't passing start_callback_server=True to JavaGateway

On the Python side: receiving callbacks from Java

Py4J explicitly creates a thread to run the CallbackServer, which accepts callback connection requests, and a thread for each callback connection request. As long as there is no concurrent callback from the Java side, the same callback connection/thread will be used.

These threads are necessary to prevent deadlocks. For example, if we only had a single thread to handle callbacks from Java, Py4J would deadlock as soon as it would encounter an indirect recursion between Java and Python functions. Early versions of Py4J made this mistake :-)


Reply all
Reply to author
Forward
0 new messages