process.waitFor() not returning



I would like to migrate data from a Postgres SQL script. I am using the code below.

void importDatabase() {

        final Process process = Runtime.getRuntime().exec("psql -f ./test.sql postgresql://postgres:root@127.0.0.1:5432/testdb");

        //Wait to get exit value
        try {
            if (process.waitFor() != 0) {
                String line;
                BufferedReader input = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                while ((line = input.readLine()) != null) {
                    log.error(line);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
}

waitFor is not returning anything, it just waits forever.

Note: My test.sql has many queries so it will display many log entries.

Question:

  1. How to solve this problem?

  2. If this relates to the buffer memory, how do I clear the buffer?

Thank you.

Answer

If a process executed by Runtime.exec() produces output — either to stdout or stderr — then for it to operate robustly you need to start consuming the output before calling Process.waitFor(). Most likely, your psql process is blocked because it’s waiting for something to read its output, and you don’t start to do that until Process.waitFor() is complete.

You probably need to consume the output in a separate thread, unless you know exactly what output is expected. In any case, there may, or may not, be a problem with your invocation of psql — unless you capture its output you probably won’t know.

Robust and portable use of Runtime.exec() is surprisingly difficult. I’ve written about this at length, with code samples, here:

http://kevinboone.me/exec.html



Source: stackoverflow