I have to write a program that is required to run several other programs via command line calls. Program 1 produces a file that program 2 then reads. I have followed various examples on how to do this safely but still have one annoying problem . The code below largely works, but only if the system.out after the waitfor() is present. If I take this out I get error (see below). I am somewhat uncomfortable with the code if I don’t know why something is happening.
Any help appreciated.
Code:
public static int executeCommandWithOutputfile(String command,
String outputFile) {
int exitVal = 0;
try {
FileOutputStream fos = new FileOutputStream(outputFile);
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(),
"ERROR");
// any output?
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(),
"OUTPUT", fos);
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
exitVal = proc.waitFor();
//don't remove this system out, when I did I got errors.
//System.out.println("ExitValue: " + exitVal);
fos.flush();
fos.close();
} catch (Throwable t) {
t.printStackTrace();
}
return exitVal;
}
Output with System.out line intact:
ExitValue: 0
ExitValue: 0
ExitValue: 0
Release note complete.
Output with system.out removed:
[Fatal Error] tmpRelNote2482381115742032425xml:1:1: Premature end of file.
Error : The XML config file is not valid!
Exception in thread "main" java.lang.NullPointerException
at rwe.release.CreateReleaseNote.insertReleaseInfo(CreateReleaseNote.java:96)
at rwe.release.CreateReleaseNote.writeReleaseNote(CreateReleaseNote.java:81)
at rwe.release.CreateReleaseNote.<init>(CreateReleaseNote.java:30)
at rwe.release.CreateReleaseNote.main(CreateReleaseNote.java:19)
Process exited with exit code 1.
Your code has a race condition. The
OutputGobblermay or may not be finished gobbling the output of the process when you callfos.close(). Theprintlnslows this thread down enough to give the gobbler time to finish processing the output of the process.You must make sure the
OutputGobblerhas finished transferring all the output to the file before you close the file.