Search code examples
javapythonjythonjpypepy4j

Different / better approaches for calling python function from Java


I am quite new to python and am trying to call python's function from java.

My primary requirements are these:

  • call should be transparent, in the sense that it should not require modifying .py file simply to enable it to be called from java. I might be given any python file with some functions inside it. I should be able to call any of these functions without requiring to modify .py file.
  • I want to be able to send arguments of both primitive types (int, String, floats etc.) or non primitive types (HashMap,ArrayList) from java to python function and receive back the returned object (which may of primitive types or non-primitive types) from python to java. I am also using pandas DataFrame and numpy ndarray and hence also want to be able to send and receive corresponding objects to and from java.
  • I preferably want to stick to CPython instead of Jython because I might need to use newer libraries that might not be available in Jython.

There are several options that I found online. Few are:

  • Use Jython's PythonInterpreter with which I am able to invoke python function without requiring any changes to .py script file:

    py1.py

     def square2(list):
         squares = []
         for i in list:
             squares.append(i*i)
         return squares
    

    JythonTest.groovy

     import org.python.util.PythonInterpreter
     import org.python.core.*;
    
     class JythonTest
     {
          static main(def args)
          {
              PythonInterpreter pi = new PythonInterpreter()
              pi.exec("from py1 import square2")
              PyFunction pf = (PyFunction)pi.get("square2")
              println pf.__call__(new PyList([1,2,3,4]))[2]   //9
          }
     }
    

    I am very well able to satisfy my needs. But its not CPython.

  • Use ScriptEngine: This is very similar to PythonInterpreter. But agains its Jython. Also, unlike PythonInterpreter, we cannot work with Jython 2.5+ and cannot directly access PyObjects. So this option can be very well closed.

  • Use py4j: Cant find example which is as minimal as in case of Jython PythonInterpreter
  • Use java2python. But not much information is given about calling python from java so that I can conclude whether my above requirements can be satisfied. Can anyone shed more light on this? More specifically if we can write the code as minimal as the one in Jython PythonInterpreter.
  • Use JPype: However after quick go through I feel I will not be able to write as minimal code as in case of Jython PythonInterpreter. Also I felt the project somewhat not under developement. Is it?

It seems that Jython PythonInterpreter is the best choice if I have understood all above approaches correctly. Have I made mistakes while grasping them? Also is there any other better option?


Solution

  • There is no current answer to this problem. Using CPython relies on the execution of Python bytecodes, which in turn requires that the Python interpreter be embedded in the execution environment. Since no Java runtime comes with an embedded Python interpreter, it really does look as though Jython is the best answer.

    Sometimes the answer you want just isn't available!