Reputation: 375
I need to write a groovy script, that is executing a external program and print the output of that program to the console.
Here is the regarding code snippet:
def pmdCommand = "${scriptDir}/run.sh pmd -d ${filesToAnalyse}"
def sout = new StringBuffer()
def serr = new StringBuffer()
def process = pmdCommand.execute()
process.consumeProcessOutput(sout, serr)
process.waitFor()
if (process.exitValue() !=0 ) {
System.err << serr.toString()
System.exit(-1)
}
else {
System.out << sout.toString()
System.exit(0)
}
I did something similar in Java, but I can't translate it to groovy.
StringBuffer output = new StringBuffer();
String s = null;
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
while ((s = stdError.readLine()) != null) {
System.err.println(s);
}
System.exit(0);
}
catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
Update: I seems the waitFor() never returns and blocks the execution
Solution provided by Emmanuel Rosa:
def pmdCommand = "/usr/src/app/lib/pmd/bin/run.sh pmd -d ${filesToAnalyse} -f codeclimate -R ${ruleset} -l apex -v 35"
def sout = new StringBuffer()
def serr = new StringBuffer()
def process = pmdCommand.execute()
process.consumeProcessOutput(sout, serr)
process.waitForProcessOutput()
System.out << sout.toString()
System.exit(0)
Upvotes: 4
Views: 10186
Reputation: 9895
The documentation states that consumeProcessOutput()
...
Gets the output and error streams from a process and reads them to keep the process from blocking due to a full output buffer. The processed stream data is appended to the supplied OutputStream. For this, two Threads are started, so this method will return immediately.
So far so good. Here's the important part...
The threads will not be join()ed, even if waitFor() is called.
And the solution...
To wait for the output to be fully consumed call waitForProcessOutput().
So what you can do is replace process.waitFor()
with process.waitForProcessOutput()
.
Upvotes: 6