javapythonpy4j

py4j: how to launch the java Gateway from Python


I am able to interact with my sample Java program in Python, by opening my Java program and then using the following Python code:

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

However this has the disadvantage that I have to somehow open the Java program before using this code.

I found that there is a method called launch_gateway which seems very convenient soo to this aim.

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

However, I am unable to connect to my Java program if launched in this way.

I tried to use the following code:

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

But I get the following error:

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

I guess I am doing something wrong in the way I try to connect to the gateway.

Any suggestion?

Thanks


Solution

  • Barthelemy, you are right! I initially misinterpreted how this works.

    launch_gateway runs the gateway in py4j.jar, which is useful to interact with a standard JVM, but obviously does not contain custom code.

    However, as you suggested, the classpath parameter allows you to load additional custom Java code.

    This is a "minimal example":

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

    Note that my_jar.jar does not have to start a gateway.

    launch_gateway gives you nice features such as: die_on_exit, stdout/stdin redirection, and automatic port selection.