4

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)
2
  • What's wrong with your groovy version of the code? Commented May 11, 2016 at 13:00
  • @tim_yates I updated my groovy code above and It seems the waitFor() method never returns Commented May 11, 2016 at 15:02

1 Answer 1

6

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().

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, this was not the only problem, but definitely a part of the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.