Issue in calling Python code from Java (without using jython)

不想你离开。 提交于 2020-08-07 04:03:23

问题


I found this as one of the ways to run (using exec() method) python script from java. I have one simple print statement in python file. However, my program is doing nothing when I run it. It neither prints the statement written in python file nor throws an exception. The program just terminates doing nothing:

Process p = Runtime.getRuntime().exec("C:\\Python\\Python36-32\\python.exe C:\\test2.py");

Even this is not creating the output file:

Process p = Runtime.getRuntime().exec("C:\\Python\\Python36-32\\python.exe C:\\test2.py output.txt 2>&1");

What is the issue?


回答1:


I think you could try your luck with the ProcessBuilder class.

If I read the Oracle documentation correctly, the std inputs and outputs are directed to pipes by default but the ProcessBuilder has an easy method for you to explicitly set output (or input) to a file on your system or something else.

If you want your Python program to use the same output as your Java program (likely stdout and stderr), you can use stg like this:

ProcessBuilder pb = new ProcessBuilder("C:\\Python\\Python36-32\\python.exe", "C:\\test2.py");
pb.redirectOutput(Redirect.INHERIT);
Process p = pb.start();



回答2:


You can use the ProcessBuilder API, redirecting the output to a file and then wait for the result.

public class Main {

    public static final String PYTHON_PATH = "D:\\Anaconda3\\python.exe";
    public static final String PATH_TO_SCRIPT = "D:\\projects\\StartScript\\test.py";

    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(PYTHON_PATH, PATH_TO_SCRIPT);

        // Redirect output to a file
        builder.redirectOutput(new File("output.txt"));

        builder.start().waitFor();

        // Print output to console
        ProcessBuilder.Redirect output = builder.redirectOutput();
        File outputFile = output.file();
        BufferedReader br = new BufferedReader(new FileReader(outputFile));

        String st;
        while ((st = br.readLine()) != null) {
            System.out.println(st);
        }

    }
}

The python file test.py contains a simple print statement:

print("Hello from python")

I guess it would be even simpler, if you do not need to wait for the result.

Using the Process API should work, too.

Like in your example (I am using the same constants declared above):

Process p = Runtime.getRuntime().exec(PYTHON_PATH + " " + PATH_TO_SCRIPT);
p.waitFor();

byte[] buffer = new byte[1024];
byte[] errBuffer = new byte[1024];

p.getInputStream().read(buffer);
p.getErrorStream().read(errBuffer);

System.out.println(new String(buffer));
System.out.println(new String(errBuffer));

To see the output of the print statement, you need to wait and redirect the streams. Same for the error stream.

Now if you break the python script like this:

print("Hello from python')

you should be able to see the error printed as well.




回答3:


One way to start a python process is using an entrypoint - test.cmd

echo Hello
python hello.py

here is hello.py

#!/usr/bin/env python3
import os
if not os.path.exists('dir'):
    os.makedirs('dir')

Here is my Java code:

public static void main(String[] args) throws IOException {
    try {
        Process p = Runtime.getRuntime().exec("test.cmd");
        p.waitFor();
        Scanner sc = new Scanner(p.getInputStream());
        while(sc.hasNextLine()){
            System.out.println(sc.nextLine());
        }
        sc.close();
    } catch (Exception err) {
        err.printStackTrace();
    }
}


来源:https://stackoverflow.com/questions/54359170/issue-in-calling-python-code-from-java-without-using-jython

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!