Java – Execute external program using ProcessBuilder and provide input

java

I'm trying to execute an external program with Java using ProcessBuilder, but it expects input from the user.

To be more specific, the program is PGSQL (Postgres SQL), when it's executed the program prompts the user for a password. The only way to bypass that is to save a file in the user home containing the passwords, I'm trying to avoid that, so I want to execute the program from Java and send the password using the process' output stream.

The code works fine when the program doesn't expect any user input, but when I delete the password file from the user home, the program hangs. I see that it's being executed, but nothing happens. If I debug it, it reaches the while and then nothing happens until I kill the process.

This is the code, any help will be greatly appreciated.

@Test
public void testSQLExecution() throws Exception {
String path = "C:/tmp";
List<String> commandList = new ArrayList<String>();
commandList.add("psql");
commandList.add("-f");
commandList.add("test.sql");
commandList.add("-h");
commandList.add(HOST);
commandList.add("-p");
commandList.add(PORT);
commandList.add("-U");
commandList.add(DATABASE);
commandList.add(SCHEMA);

ProcessBuilder processBuilder = new ProcessBuilder(commandList);
processBuilder.directory(new File(path));
processBuilder.redirectErrorStream(true);

Process p = processBuilder.start();

String line;
BufferedReader input = new BufferedReader(new InputStreamReader(p
    .getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p
    .getOutputStream()));

out.write("password");
out.newLine();
out.flush();
out.close();

    // When this line is reached, the execution halts.
while (input.ready() && (line = input.readLine()) != null) {
    System.out.println(line);
}

if (p.waitFor() != 0) {
    Assert.fail("The process did not run succesfully.");
}

input.close();
}

Thanks a lot.

Best Answer

I believe the prompt is going to STDERR, not STDOUT, so you'll have to open a stream connected to that and read there. When you try to read from STDOUT your code hangs waiting for output that will never arrive.

EDIT: I see you have redirected the error stream in the ProcessBuilder.

One other possibility is that the BufferedReader is waiting for a newline to finish reading, and the prompt does not end with a newline.

Related Topic