0

On Windows 7 64 bit, running 64 bit Java 1.7.0_17 , the p.waitFor() shown below never returns.

String move_command="cmd.exe /c xcopy /Y /E "+x86_release+" "+path+"\\";
Process p;
p = Runtime.getRuntime().exec(move_command);
p.waitFor();

If I use Windows Explorer, it looks like all the files are copied (same number, same size, etc.)

If I do the below, it waitFor() does return:

String move_command="cmd.exe /c move /Y "+x86_release+" "+path+"\\";
Process p;
p = Runtime.getRuntime().exec(move_command);
p.waitFor();

What could be so different between an xcopy and a move that keeps waitFor() from returning, or am I on the wrong track entirely?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
kmort
  • 2,848
  • 2
  • 32
  • 54
  • do the files copy correctly if you comment out the p.waitFor()? – Farlan May 14 '13 at 14:45
  • 2
    Yet Another Fragile Use of Exec. Go through the JavaWorld article linked from the [exec info. page](http://stackoverflow.com/tags/runtime.exec/info) & implement **all** the recommendations. Then split the `move_command` into a `String[]` and use `ProcessBuilder` to create the process. – Andrew Thompson May 14 '13 at 14:48
  • Wow that was a quick response. I'm not a Java person, and I expected `waitFor()` to behave like a C/C++ `system()` call. Thanks to all your input, I now know it certainly does not. One other thing to mention, I took the easy way out (because I don't care about the output of the copy command) and redirected the output to NUL. Final successful command was `"cmd.exe /c xcopy /Y /E "+x86_release+" "+path+"\\ >NUL 2>&1"` (had to keep the `cmd.exe /c` to get redirection to work) – kmort May 14 '13 at 15:18
  • One other thing to mention about my above comment... the easy way out ended up being as fragile as Andrew Thompson mentions. In the end, I fixed it as he recommended using the JavaWorld article. – kmort Sep 09 '13 at 13:30

2 Answers2

1

I suspect you're not consuming the process standard out/err, and that's blocking the process. If your code doesn't consume this output, then the spawned process will hang (and you'll hang waiting for that process!). Why the difference in behaviour between the two commands ? Probably due to the quantity of data returned and the impact on the publishing buffers.

See this answer for more details.

I would also investigate Apache Commons FileUtils.copyDirectory() such that you don't have to spawn a whole new process to copy files.

Community
  • 1
  • 1
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
1

xcopy probably just happens to produce more output than move, filling up the out-buffer and blocking until it is flushed. The default behavior in Java is to pipe the subprocess's stdout/stderr into InputStreams that you are then required to read programmatically lest the subprocess's buffers overflow.

If the latter is the case, the solution is simple, and in fact you should do that anyway: use ProcessBuilder to prepare the system call and call inheritIO on it. This will reuse your parent process`s stdin and stdout for the subprocess.

A side note, xcopy is a regular .exe file and doesn't need wrapping into cmd.exe /c.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436