0

I am trying to run plink in my own console window. I started by using Process.exec() and that worked fine. The I moved to using ProcessBuilder and now the output is not sent out until I kill the process.

My code looks like this:

    class ConsoleOutputThread extends Thread {

    public void start(String processName) {
        // this was old code: Runtime r = Runtime.getRuntime();
        try {
            builder = new ProcessBuilder("plink", "-ssh", "192.168.3.21");
            builder.redirectErrorStream(true);
            process = builder.start();
            //this was old code: process = r.exec (processName);
        } catch (IOException ex) {
        }
        start();
    }

    @Override
    public void run() {
        try {
            BufferedReader is = new BufferedReader(new InputStreamReader(process.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
            try {
                process.waitFor();
            } catch (InterruptedException ex) {
            }
            char    b[];
            b = new char[1];
            while(is.read(b, 0, 1)> 0) {
                // this is for debug, normally sent to console
                System.out.println("Got character: " + b[0]);
            }
        } catch (IOException ex) {
        }
    }
}

So, when using Runtime.exec() everything worked fine. Now, with ProcessBuilder, the read function blocks forever (actually until I kill the process, when everuthing is spitted out). However, the error stream works, i.e. if I put a bad option I get the messages in the console. I am probably missing something here and looking for help. Thank you

1 Answers1

0

You've set the plink process to write its output to a pipe which is connected to the java process. Anything output by the plink process will be saved in an operating-system buffer until your process reads it. The OS buffer has a limited capacity,, and if plink writes too much data, then it will block until your process reads some data from the buffer.

Unfortunately, the java process waits for the plink process to complete before reading anything from the pipe. So, if the plink process writes too much output, it will block indefinitely.

You should change the java logic to read the plink process's output before calling waitfor().

Kenster
  • 23,465
  • 21
  • 80
  • 106
  • You are somehow right, except that the plink does not sent too much output, but it waits for another process to complete (ssh). It asks for a password and until it gets connected and authenticated it stays in waitFor(). So, if I comment out waitFor(), it will go ahead. However, the output of ssh ("root@192.168.3.21's password:")does not go to my input stream, it goes to the console from where I started the jar file (this in in Linux, in Windows I think plink is implemented different). So the question becomes 'How to redirect the output for a process which calls another process?' – Adrian Bica Sep 26 '13 at 15:54