Edit 20140716:
Solution found
tl;dr = exec-maven-plugin does not recognise .cmd
files, but only .bat
files, as executable scripts. Rename grunt.cmd --> grunt.bat
, bower.cmd --> bower.bat
, etc. as a workaround.
Having done npm install -g grunt-cli
on my system, grunt
is most certainly on the PATH
When I run maven install
however, this doesn't seem to register.
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
(build-spa-bower) on project foobar: Command execution failed.
Cannot run program "grunt" (in directory "C:\workspace\foobar\src\main\spa"):
CreateProcess error=2, The system cannot find the file specified -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException:
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
(build-spa-bower) on project foobar: Command execution failed.
Just to be sure, in the same terminal, I have executed this
cd C:\workspace\foobar\src\main\spa
grunt build
... in the same terminal as I issued the maven command above, and grunt executes just fine.
Does exec-maven-plugin
use the PATH
environment variable, or does it need to be told that this executable exisst in some other way?
EDIT:
This documentation suggests that executables on PATH
should be found, so it stumps me further.
In addition to bguiz' answer, which would be the best solution, I've created a workaround using Maven profiles, bypassing the problem.
This is a temporary solution, until the maven-exec-plugin's bug gets fixed.
Please upvote the bug report here: http://jira.codehaus.org/browse/MEXEC-118
Edit: The bug is resolved, you can point to 1.4-SNAPSHOT to fix it.
<project>
(...)
<profiles>
<profile>
<id>grunt-exec-windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
<executions>
<execution>
<id>grunt-default</id>
<phase>generate-resources</phase>
<configuration>
<executable>cmd</executable>
<arguments>
<argument>/C</argument>
<argument>grunt</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
I dug into the source code of exec-maven-plugin
and found this snippet.
From the source of ExecMojo#getExecutablePath
:
CommandLine toRet;
if ( OS.isFamilyWindows() && exec.toLowerCase( Locale.getDefault() ).endsWith( ".bat" ) )
{
toRet = new CommandLine( "cmd" );
toRet.addArgument( "/c" );
toRet.addArgument( exec );
}
else
{
toRet = new CommandLine( exec );
}
I compared this to another plugin that ran grunt tasks from maven, and found this
if (isWindows()) {
command = "cmd /c " + command;
}
... and that worked for me. So essentially the latter worked because all commands in WIndows were prepended with cmd /c
,
whereas the exec-maven-plugin
did not, because it only did so for file ending in .bat
.
Looking in C:\Users\USER\AppData\Roaming\npm
, I see:
node_modules
(folder)
grunt
(unix script file)
grunt.cmd
(windows script file)
When I rename grunt.cmd
--> grunt.bat
, this solves the problem, and exec-maven-plugin
is able to run this command.
(this also applies to other executables created using npm install -g
, such as bower
and yo
)
I had the same issue with 1.5.0 of the plugin.
The cause in my case was spaces in my user name resulting in a grunt path:
C:\Users\My name with spaces\AppData\Roaming\npm.
When I moved the contents of the npm directory to a path without spaces, it worked.