py4j - How would I go about on calling a python method in java
Asked Answered
C

1

10

I've recently discovered py4j and was able to call static java methods from python. Now I want to call python methods from java. I couldn't find much documentation so this is the last place I can think of that might tell me if it's possible, and how.

Corvine answered 18/4, 2014 at 15:41 Comment(1)
Possible duplicate: #14450673Resorcinol
R
13

You can call a Python method from Java by implementing a Java interface on the python side.

The steps are:

  1. Create an interface in Java, e.g., py4j.examples.Operator
  2. In Python, create a class and inside the class, create a Java class with an "implements" field.
  3. In Python, instantiate a gateway with start_callback_server=True, e.g., gateway = JavaGateway(start_callback_server=True)
  4. In Python, instantiate the class implementing a Java interface and send it to the Java side.
  5. In Java, call the interface.

Example adapted from the Py4J documentation:

Java code:

// File 1
package py4j.examples;

public interface Operator {
        public int doOperation(int i, int j);
        public int doOperation(int i, int j, int k);
}

// File 2
package py4j.examples;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import py4j.GatewayServer;

public class OperatorExample {

    // To prevent integer overflow
    private final static int MAX = 1000;

    public List<Integer> randomBinaryOperator(Operator op) {
        Random random = new Random();
        List<Integer> numbers = new ArrayList<Integer>();
        numbers.add(random.nextInt(MAX));
        numbers.add(random.nextInt(MAX));
        numbers.add(op.doOperation(numbers.get(0), numbers.get(1)));
        return numbers;
    }
}

Python code:

from py4j.java_gateway import JavaGateway

class Addition(object):
    def doOperation(self, i, j, k = None):
        if k == None:
            return i + j
        else:
            return i + j + k

    class Java:
        implements = ['py4j.examples.Operator']

if __name__ == '__main__':
    gateway = JavaGateway(start_callback_server=True)
    operator = Addition()
    operator_example = gateway.jvm.py4j.examples.OperatorExample()

    # "Sends" python object to the Java side.
    numbers = operator_example.randomBinaryOperator(operator) 
Resorcinol answered 19/4, 2014 at 12:44 Comment(5)
Great example. Could you tell how this can be achieved with py4j 0.8.2.1Uhlan
can we call python function given .py file without requiring to modify python script. Using Jython PythonInterpreter, we can straight a way call function defined in the python file. Is something similar possible with py4j?Rolle
@Rolle no, it's not possible to just interpret straight python code from Java, but you might be interested in Eclipse EASE which provides an environment where this is somehow possible.Resorcinol
hey, thanks for the nice example. i need to call python from java side too but the python function should return an huge array of float values. how can i do that?Charge
Here, the python code is 'sending' object to Java. If I want control flow such that Java code can call python function, when required. Is it possible with py4j ?Objurgate

© 2022 - 2024 — McMap. All rights reserved.