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

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>

JFYI, the issue is fixed in exec-maven-plugin v 1.3.2 - http://blog.soebes.de/blog/2014/07/28/mojo-exec-maven-plugin-version-1-dot-3-2-released/

The exec-maven-plugin uses an output stream that does not flush automatically.
I think you have two options:
Copy and change the exec-maven-plugin to suit your needs.
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.

As Ivan already pointed out exec-maven-plugin:1.3 doesn't automatically flush the output stream. This can lead to delayed output.
I observed that this behaviour is only present in the plugin from version 1.3 onward.
exec-maven-plugin:1.2.1 actually has the desired behaviour and flushes the output stream. So instead of using ant you could switch to an older version of exec-maven-plugin.

Related

How to set up JASMINE using MAVEN-PLUGIN?

I have a folder structure like
-root
-pom.xml
-service
-web
-pom.xml
-src
-main
-test
-java
-javascript
-lib
-specRunner.js
-runner.html
-spec
-model
-view
-collection
I have written JASMINE test cases in the "spec" folder containing "model","views","collections".
I'm able to see my test results in runner.html.
Now i'm trying to integrate with MAVEN build. SO followed steps given in http://searls.github.io/jasmine-maven-plugin
But i'm getting build failure when doing mvn clean install and unable to see anything on localhost:8234 when doing mvn jasmine:bdd
I'm unable to find out what went wrong. The errors in console show something about require js.
Following is my POM.xml for jasmine-maven plugin
<plugin>
<groupId>com.github.searls</groupId>
<artifactId>jasmine-maven-plugin</artifactId>
<version>1.3.1.5</version>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<jsSrcDir>${project.basedir}/src/main/webapp/js</jsSrcDir>
<jsTestSrcDir>${project.basedir}/src/test/javascript</jsTestSrcDir>
<specRunnerTemplate>REQUIRE_JS</specRunnerTemplate>
<preloadSources>
<source>${project.basedir}/src/main/webapp/js/libs/require.js</source>
</preloadSources>
</configuration>
</plugin>
Can anybody guide what is wrong or better provide some demo project (Backbone+Require+Jasmine) which is integrated with MAVEN build.
Thanks in Advance.
I read some blogs and tried editing my jasmine-maven plugin as follows
<plugin>
<groupId>com.github.searls</groupId>
<artifactId>jasmine-maven-plugin</artifactId>
<version>1.3.1.5</version>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
<configuration>
<debug>true</debug>
<specRunnerTemplate>REQUIRE_JS</specRunnerTemplate>
<sourceExcludes>
<exclude>lib/jasmine.js</exclude>
<exclude>lib/jasmine-html.js</exclude>
<!--<exclude>libs/text.js</exclude>-->
</sourceExcludes>
<preloadSources>
<source>${basedir}/src/main/webapp/js/libs/require.js</source>
<source>${basedir}/src/main/webapp/js/main.js</source>
</preloadSources>
<jsSrcDir>${basedir}/src/main/webapp/js</jsSrcDir>
<sourceIncludes>
<include>${basedir}/src/main/webapp/jslibs/*.js</include>
<!--<include>libs/jquery-1.9.1.js</include>
<include>libs/underscore-min.js</include>
<include>libs/backbone-min.js</include>
<include>libs/text.js</include>-->
<!--<include>../templates/*.tmpl</include>-->
</sourceIncludes>
<haltOnFailure>true</haltOnFailure>
<jsTestSrcDir>${basedir}/src/test/javascript</jsTestSrcDir>
<serverPort>8234</serverPort>
<specIncludes>
<include>spec/**/*.js</include>
</specIncludes>
<!--<specRunnerHtmlFileName>runner.html</specRunnerHtmlFileName>-->
</configuration>
</execution>
</executions>
</plugin>
Now i'm able to check the JASMINE specs in the console while mvn clean install as follows-
Caused by: net.sourceforge.htmlunit.corejs.javascript.JavaScriptException: Error: src/views/../../templates/menu.tmpl HTTP status: 404
I'm getting errors on template files (exceptions) not sure what this is about.
Any help on this?
Thanks.

Error messages eaten somewhere along exec-maven-plugin > Node.js > r.js

We're using exec-maven-plugin to run RequireJS's optimizer (r.js) under Node.js (because it's a lot faster than Rhino):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>compile-js</id>
<phase>prepare-package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${node.executable}</executable>
<arguments>
<argument>${project.build.directory}/dependency/requirejs/r.js</argument>
<argument>-o</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
The issue is, whenever there's any issue during compilation, the error messages that r.js is supposed to blurt out are not shown in Maven's console output. What I do to troubleshoot is, I rerun the Maven command with the -X flag to get debug output so that exec-maven-plugin outputs the actual command being executed. It's something like:
project-root/target/dependency/node/node \
project-root/target/dependency/requirejs/r.js \
-o src/main/webapp/app.build.json
When I run the command manually from the command line, I then get the actual compilation errors in the console and then proceed to fixing them.
I've experimented with redirecting stderr to stdout with 2>&1 to no avail (on Windows) because I couldn't immediately find a way to make exec-maven-plugin like the redirection bit as an argument. I didn't pursue that route too far because it's just a wild guess that this is a stderr/stdout issue -- it could be, but I'm merely speculating.
Any pointers to as to what may be happening, or any suggestions for further diagnostic steps that I can take? Please remember there are multiple moving parts in this problem: Maven, exec-maven-plugin, Node.js, r.js, and one tired head.
P.S. I'm considering giving requirejs-maven-plugin a shot as a last resort because the project timeline doesn't allow me to do a complete overhaul of the POM right now. I'm trying to see if there's anything I can do with the current setup.
How about wrapping the call to node.js and r.js in a script, that you then call from the maven-exec plugin?
From a look at r.js, it seems to use console.log for it's output. Maybe running it from a shell script will allow you to catch the output, pipe it into a file, regex for an errors, etc.
Depending on the OS, this might be easy to do.

appassembler maven plugin doesn't set "execute" permissions on generated script

The AppAssembler Maven plugin does a great job of generating distribution for me. One last problem is that the generated Shell script does not have execution permissions so I need to set them manually.
I am on Linux RedHat
Does anybody know of a clean way to set them automatically?
The only way to do this is to process the file with another maven plugin like Antrun or Assembly after running AppAssembler.
This issue (see link below) has been brought up on the AppAssembler project issue tracker and it was rejected as Won't Fix.
Issue: MAPPASM-54
I think it can be set in your assembly.xml, in the fileSet tag:
<fileSets>
<fileSet>
<directory>src/resources/bin</directory>
<lineEnding>keep</lineEnding>
<useDefaultExcludes>true</useDefaultExcludes>
<outputDirectory>bin</outputDirectory>
<includes>
<include>*.bat</include>
<include>*.sh</include>
</includes>
<fileMode>744</fileMode>
</fileSet>
...
Since Maven 3.0.3 all plugins are executed in the order they are in your pom.xml. So setting the executeable flag in a platform independet manner is as easy as using the maven-enforcer-plugin right after your appassembler plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce-beanshell</id>
<phase>package</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<evaluateBeanshell>
<condition>
import java.io.File;
print("set executable for file ${basedir}/dist/bin/mql");
new File("${basedir}/dist/bin/mql").setExecutable(true,false);
true;
</condition>
</evaluateBeanshell>
</rules>
<fail>false</fail>
</configuration>
</execution>
</executions>
</plugin>

Where to get a full list of pre-defined variables in gmaven-plugin?

Where to get a complete list of variables available in Groovy scripts executed under gmaven-plugin in Maven? Besides that, maybe someone knows where to find Gmaven documentation?
I'm aware about project and settings. I assume there are some others..
The page http://docs.codehaus.org/display/GMAVEN/Executing+Groovy+Code lists:
Default Variables
By default a few variables are bound into the scripts environment:
project The maven project, with auto-resolving properties
pom Alias for project
session The executing MavenSession
settings The executing Settings
log A SLF4J Logger instance
ant An AntBuilder instance for easy access to Ant tasks
fail() A helper to throw MojoExecutionException
This snippet in your pom should give you a better idea of what's available while running the script. Most of the interesting bits are probably in the binding.project, an instance of MavenProject.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<properties>
<hello>world</hello>
</properties>
<source>
println this.binding.variables
println project.properties
println settings.properties
</source>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Setting environment variable with maven 2.x

Is it possible to set environment variable with maven (OS: Linux)?
I already have user-defined properties (in the pom and in profiles.xml)....my problem is, how to execute following from Maven
export GGA_FRE=/path
So will be possible, that every developer can set his own path for the GGA_FRE.
This answer is not correct, at least not completely (see comments).
Unfortunately I can't delete it as it has been accepted. Your milage may vary.
Use the exec:exec mojo.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>exportVar</id>
<phase>initialize</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>export</executable>
<arguments>
<argument>GGA_FRE=${my.path}</argument>
</arguments>
</configuration>
</plugin>
now call it like this mvn install -Dmy.path=/var/users/groucho
I don't think there is a Java way to set environment variable the way export command does (so that it is avaliable outside of Java). (see for example this question: How do I set environment variables from Java?)
However, you might hack you way around: for example use maven-exec plugin to run a shell script and then set the variable in the script. You might pass a parameter to your script to specify the variable value.
(note that I have not tested this)

Resources