tags:

views:

766

answers:

3

I'm creating a process on Windows from Java. My problem is that this process doesn't terminate. Here's a sample program:

import java.io.IOException;

public class Test {

/**
 * @param args
 * @throws IOException
 * @throws InterruptedException
 */
public static void main(String[] args) throws IOException,
  InterruptedException {
 Process process = Runtime.getRuntime().exec("cmd /c dir");
 process.waitFor();
    }
}

For reasons beyond my understanding, this program never completes. This is true if "cmd /c dir" is replaced with ipconfig as well as other things.

I can see using ProcessExplorer that java creates the cmd process. This sample is obviously a simplification; in my original program I found that if I call process.destroy() after a while and check the cmd process output, the command is executed successfully.

I've tried this with various releases of Java 1.5 and 1.6. My OS is Windows XP Pro, SP 2.

Any suggestions would be appreciated.

-David

+4  A: 

Likely that you just need to read the stdout and stderr of the process, or it will hang since its output buffer is full. This is easiest if you redirect stderr to stdout, just to be safe:

public static void main(String[] args) throws IOException,
                InterruptedException {
        String[] cmd = new String[] { "cmd.exe", "/C", "dir", "2>&1" };
        Process process = Runtime.getRuntime().exec(cmd);
        InputStream stdout = process.getInputStream();
        while( stdout.read() >= 0 ) { ; }
        process.waitFor();
    }
}
Eric Petroelje
+9  A: 

See this link for an explanation.

You need to read the input stream. Also the java process doesn't work like a dos shell. You need to pass the arguments yourself:

String[] cmd = new String[3];
cmd[0] = "cmd.exe" ;
cmd[1] = "/C" ;
cmd[2] = "dir";
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
kgiannakakis
+1 for catching the argument passing problem as well.
Eric Petroelje
You're not entirely correct. The API docs for exec(String) states that the argument is "a system command", without any closer definition of "system command". It is not unlikely that the JVM just passes the string to cmd.exe.
JesperE
Thanks for the answer and link! I should have the chance to check it on the problematic machine on Sunday. Actually, the arguments are passed correctly; I can see them in Process Explorer.
abunetta
A: 

You should try using a ProcessBuilder as shown below. Not sure whats different but this solved a LOT of problems for us.

ProcessBuilder pb = new ProcessBuilder(CMD, ARG1, ARG2);
Process p = pb.start();

Adam Lerman