Search code examples
linuxbashshellmavenexec-maven-plugin

How to display the output of the exec-maven-plugin instantaneously


I'm using Maven 3.1.1 and the exec-maven-plugin (1.3) in order to execute a bash script during a build job.

The bash script produces output on stdout with echo and printf. I've noticed that the output of the script is not written to the maven console output instantaneously. Instead the maven console output "freezes" until it gets updated with multiple output lines of the bash script at once. I don't know what's the trigger for an update of the maven output (timeout? full output buffer?) but it's very slow.

Let's take a very simple bash script, e.g. counter.sh:

#!/usr/bin/env bash
for i in `seq 1 1000`; do
  echo $i
  sleep 0.5
done 

And here's my plugin configuration in the pom.xml:

<plugin>
    <artifactId>exec-maven-plugin</artifactId>
    <groupId>org.codehaus.mojo</groupId>
    <version>1.3</version>
    <executions>
        <execution>
            <id>execute-script</id>
            <phase>package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>${project.build.directory}/executable/counter.sh</executable>
            </configuration>
        </execution>
    </executions>
</plugin>

When I execute the build job with mvn clean package, the maven output freezes at the exec-maven-plugin and shows no progress/output until the script has completed after ~8 minutes.

When I execute another script that is running even longer, I get a block of output each ~15 minutes.

What I'm looking for is a way to see the output of the bash script instantaneously in the maven console output.

Update: Solution using maven-antrun-plugin (thanks to Ivan)

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <id>execute-script</id>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <exec dir="${project.basedir}" executable="${project.build.directory}/executable/counter.sh" />
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

Solution

  • The exec-maven-plugin uses an output stream that does not flush automatically.

    I think you have two options:

    1. Copy and change the exec-maven-plugin to suit your needs.
    2. Use antrun plugin with ants exec task. This does flush the output stream so you can see the output when it comes. See http://sanchitbahal.wordpress.com/2011/09/19/maven-exec-plugin-vs-maven-antrun-plugin-for-running-command-line-tool/

    Maybe the 2nd option could be slower, since maven calls ant, and ant then calls your script, but is pretty easy.