I'm trying to execute python code (live from the console, not just opening a single file).
ProcessBuilder builder = new ProcessBuilder("python");
Process process = builder.start();
new Thread(() -> {
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
String line;
final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
// Ignore line, or do something with it
while (true) try {
if ((line = reader.readLine()) == null) break;
else System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
final PrintWriter writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream()));
writer.println("1");
writer.println("2 * 2");
I tried this code, but after trying to push the following expressions 1
and 2*2
, I don't get a response (evaluation of my expressions).
Does anyone know what the issue is?
Your python
code doesn't appear to print anything, and handling multiple threads to read and write to another process is a tricky topic; luckily, the functionality is built-in. You could do
ProcessBuilder builder = new ProcessBuilder("/usr/bin/env", "python",
"-c", "print(2*2); exit()");
builder.inheritIO();
try {
Process process = builder.start();
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
Which outputs
4
and terminates. For less trivial Python and Java integration, I would strongly suggest you look here. As for your existing code, you never exit()
python and you never flush()
your PrintWriter
. And you write on the main
thread. And you need to pass -i
to python, or it won't assume stdin is a console. Changing your code to
ProcessBuilder builder = new ProcessBuilder("/usr/bin/env", "python", "-i");
Process process = builder.start();
new Thread(() -> {
String line;
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
// Ignore line, or do something with it
while (true)
try {
if ((line = reader.readLine()) == null)
break;
else
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
final PrintWriter writer = new PrintWriter(
new OutputStreamWriter(process.getOutputStream()));
writer.println("1");
writer.println("2 * 2");
writer.println("exit()");
writer.flush();
}).start();
Seems to work properly.