0

I am using py4j for communication between python and java.I am able to call python method from java side. But from python I am not able to send any object or call java method. Here is the code i have tried.

My java code:

public interface IHello {
    public String sayHello();

    public String sayHello(int i, String s);

//    public String frompython();

}

//ExampleClientApplication.java
package py4j.examples;

import py4j.GatewayServer;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ExampleClientApplication extends Thread {

public void run(){
    System.out.println("thread is running...");
}

public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    GatewayServer.turnLoggingOff();
    GatewayServer server = new GatewayServer();
    server.start();
    IHello hello = (IHello) server.getPythonServerEntryPoint(new Class[] { IHello.class });
    try {
        System.out.println("Please enter a string");
        String str = br.readLine();
        System.out.println(hello.sayHello(1, str));
    } catch (Exception e) {
        e.printStackTrace();
    }
    ExampleClientApplication t1 = new ExampleClientApplication();
    t1.start();
    //server.shutdown();
  }
}

My python code :

class SimpleHello(object):
    def sayHello(self, int_value=None, string_value=None):
        print(int_value, string_value)
        return "From python to {0}".format(string_value)

class Java:
    implements = ["py4j.examples.IHello"]

# Make sure that the python code is started first.
# Then execute: java -cp py4j.jar 
py4j.examples.SingleThreadClientApplication

from py4j.java_gateway import JavaGateway, CallbackServerParameters
simple_hello = SimpleHello()

gateway = JavaGateway(
callback_server_parameters=CallbackServerParameters(),
python_server_entry_point=simple_hello)
stovfl
  • 14,998
  • 7
  • 24
  • 51
naik3
  • 319
  • 2
  • 8
  • 22
  • 1
    Can you be more specific about your problem? What do you mean by "not able to send"? What have you tried so far? – friedemann_bach May 24 '17 at 07:10
  • If you were able to receive "From python to ...", the Python process can definitively communicate with the Java side. You indeed need to provide more details (output, error message, etc.) – Barthelemy May 24 '17 at 23:51
  • 1. You have indent errors, I have corrected this. Check your Source about this. 2. You pass `class SimpleHello()` but no ref to `def sayHello(...`. Therfore how will `def sayHello(...` ever called? – stovfl May 26 '17 at 16:01

1 Answers1

0

The send objects problem is easily solved by implementing a getter/eval method in the java interface that is implemented by python, which can then be called from java to get the variable that is requested. For an example have a look at the py4j implementation here: https://github.com/subes/invesdwin-context-python

Specifically see the get/eval method implementation here: https://github.com/subes/invesdwin-context-python/blob/master/invesdwin-context-python-parent/invesdwin-context-python-runtime-py4j/src/main/java/de/invesdwin/context/python/runtime/py4j/pool/internal/Py4jInterpreter.py

For the other way around, you would have to do same on the java gateway class and provide a get/eval method that can be called from python. The actual java code could be executed in a ScriptEngine for groovy and the result could be returned to python. (see http://docs.groovy-lang.org/1.8.9/html/groovy-jdk/javax/script/ScriptEngine.html)

Though it might be a better idea to decide about a master/slave role and only once input the parameters, then execute the code in python and retrieve the results once. Or the other way around if python should be leading. Thus you would reduce the communication overhead a lot. For a tighter integration without as much of a performance penalty as py4j incurs, you should have a look at https://github.com/mrj0/jep to directly load the python lib into the java process. Then each call is not as expensive anymore.

subes
  • 1,832
  • 5
  • 22
  • 28