3

I wrote a Python program that consists out of five .py script files. I want to execute the main of those python scripts from within a Java Application.

What are my options to do so? Using the PythonInterpreter doesn't work, as for example the datetime module can't be loaded from Jython (and I don't want the user to determine his Python path for those dependencies to work).

I compiled the whole folder to .class files using Jython's compileall. Can I embed these .class files somehow to execute the main file from within my Java Application, or how should I proceed?

CrushedPixel
  • 1,152
  • 2
  • 13
  • 26

3 Answers3

1

Have a look at the ProcessBuilder class in java: https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html.

The command used in the java constructor should be the same as what you would type in a command line. For example:

Process p = new ProcessBuilder("python", "myScript.py", "firstargument").start();

(the process builder does the same thing as the python subprocess module).

Have a look at running scripts through processbuilder

N.B. as for the Jython part of the question, if you go to the jython website (have a look at the FAQ section of their website www.jython.org). Check the entry "use jython from java".

Community
  • 1
  • 1
Sci Prog
  • 2,651
  • 1
  • 10
  • 18
  • In this case again, I'd need to assure the user has Python 2.x installed for my script to work, it's registered as "python" command, and finally I'd need to extract the script somewhere on the hard drive. That's not what I want, I'll have a look at Jython. – CrushedPixel Mar 01 '16 at 09:23
  • Although useful information, this doesn't appear to directly answer the question of using Python code, from Java/Jython, *bypassing* the need for an installed Python runtime. Please see my [post](https://stackoverflow.com/a/51277759/304330) – Big Rich Jul 11 '18 at 05:24
1

I'm also interested in running Python code directly within Java, using Jython, and avoiding the need for an installed Python interpreter.

The article, 'Embedding Jython in Java Applications' explains how to reference an external *.py Python script, and pass it argument parameters, no installed Python interpreter necessary:

#pymodule.py - make this file accessible to your Java code
def square(value):
return value*value

This function can then be executed either by creating a string that executes it, or by retrieving a pointer to the function and calling its call method with the correct parameters:

//Java code implementing Jython and calling pymodule.py
import org.python.util.PythonInterpreter;
import org.python.core.*;

public class ImportExample {
   public static void main(String [] args) throws PyException
   {
       PythonInterpreter pi = new PythonInterpreter();
       pi.exec("from pymodule import square");
       pi.set("integer", new PyInteger(42));
       pi.exec("result = square(integer)");
       pi.exec("print(result)");
       PyInteger result = (PyInteger)pi.get("result");
       System.out.println("result: "+ result.asInt());
       PyFunction pf = (PyFunction)pi.get("square");
       System.out.println(pf.__call__(new PyInteger(5)));
   }
}
Big Rich
  • 5,864
  • 1
  • 40
  • 64
  • My above answer is more inline with executing a particular function, within a Python script. The answer at https://stackoverflow.com/a/36288406/304330 explains explicitly how to pass arguments to a Python script, via Jython, as you might from the CLi (having no understanding of the internals of the script, just the command line). I may amend my answer to reflect this new information. – Big Rich Jul 11 '18 at 05:40
0

It is possible to load the other modules. You just need to specify the python path where your custom modules can be found. See the following test case and I am using the Python datatime/math modules inside my calling function (my_maths()) and I have multiple python files in the python.path which are imported by the main.py

@Test
public void testJython() {

    Properties properties = System.getProperties();
    properties.put("python.path", ".\\src\\test\\resources");
    PythonInterpreter.initialize(System.getProperties(), properties, new String[0]);

    PythonInterpreter interpreter = new PythonInterpreter();
    interpreter.execfile(".\\src\\test\\resources\\main.py");

    interpreter.set("id", 150); //set variable value
    interpreter.exec("val = my_maths(id)"); //the calling function in main.py

    Integer returnVal = (Integer) interpreter.eval("val").__tojava__(Integer.class);
    System.out.println("return from python: " + returnVal);
}
Shehan Simen
  • 1,046
  • 1
  • 17
  • 28