-1

We can use Jython to implement python in java, but I dont want to go for that approach, what I am looking for is using command line utility and fire python command to execute the code and get the console output in java code.

python Main.py < input.txt

I used above command in terminal, it works there, giving me output, but unable to get the output in java code.

Note: Main.py and input.txt and java code in the same folder

What I am doing wrong in java code?

Here is Sample java code which I am calling in order to execute external python code

try {
    Process process = Runtime.getRuntime()
            .exec("python Main.py < input.txt");
    
        process.waitFor();
        System.out.println(process);
        StringBuilder output
        = new StringBuilder();

        BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));

        String line;
        while ((line = reader.readLine()) != null) {
            output.append(line + "\n");
        }
        System.out.println("here");

        int exitVal = process.waitFor();
        if (exitVal == 0) {
            System.out.println("Success!");
            System.out.println(output);
        } else {
            System.out.println("Process failed");
        }
} catch (Exception e) {
    // TODO: handle exception
    System.out.println(e);
}

Here is a sample python code:

x = input();
y = input();
print(type(x));
print(type(y));
print(x + y);

here is a sample input file which I am passing as a input to the python code

30
40
  • Does this answer your question? [Redirect process output to stdout](https://stackoverflow.com/questions/1732455/redirect-process-output-to-stdout) – Alex May 16 '21 at 17:28

2 Answers2

0

java process not accept < symbol to input file in python command. Instead you can run like this python file

    f = open("input.txt", "r")
    for x in f:
    print(type(x));
    print(x)

java file

        Process process = Runtime.getRuntime().exec("python Main.py  input.txt");
        process.waitFor();
        System.out.println(process);
        StringBuilder output
                = new StringBuilder();

        BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));

        String line;
        while ((line = reader.readLine()) != null) {
            output.append(line + "\n");
        }
        System.out.println("here");

        int exitVal = process.waitFor();
        if (exitVal == 0) {
            System.out.println("Success!");
            System.out.println(output);
        } else {
            System.out.println("Process failed");
        }
    } catch (Exception e) {
        // TODO: handle exception
        System.out.println(e);
    }

and use and same text file. It should print in console

sandip
  • 129
  • 5
  • Thanks sandip code is working but my use case was I can't modify python code, only java code can be modified in order to execute python program – Pranay Katariya May 17 '21 at 10:41
0

As sandip showed, executing a command in java is not the same as running commands through BASH. At first I tried to execute bash -c "python Main.py < input.txt" (through java). For some reason this didn't work, and even if it did its not a great solution as its dependent on the system its running on. The solution I found to work was by using ProcessBuilder to first make the command, and redirect its input to a file. This allows you to keep the python code unchanged, and for me at least, give the same result as just running the BASH command. Example:

         ProcessBuilder pb = new ProcessBuilder("python3","Main.py");
         //Make sure to split up the command and the arguments, this includes options
         //I only have python3 on my system, but that shouldn't affect anything
         pb.redirectInput(new File("./input.txt"));
         System.out.println(pb.command());
         Process process = pb.start();
         //The rest is the exact same as the code in the question

Heres the ProcessBuilder docs for quick reference

oname
  • 16
  • 2