Monday, 9 March 2009

Executing multiple mvn commands from a Windows bat file











When running Maven, if you try to run multiple Maven commands in a batch (.bat) file, it only runs the first one and exits to the command prompt


mvn clean
mvn package



This occurs since mvn itself is a bat file.

To overcome this, you need to stop Windows passing control to the mvn.bat script by using the call command for each call to mvn.


call mvn clean
call mvn package



Additionally, to catch failures you will need to do this


call mvn clean
echo Exit Code = %ERRORLEVEL%
if not "%ERRORLEVEL%" == "0" exit /b

call mvn package
echo Exit Code = %ERRORLEVEL%
if not "%ERRORLEVEL%" == "0" exit /b








A failure throws an ERRORLEVEL higher than 0.
Otherwise it will keep moving ahead even if it fails.

Note: if you're using maven 2.0.7 or older, there is a possibility that the mvn does not return an ERRORLEVEL > 0 for the process to exit.

Lots of examples are available here http://www.google.co.uk/search?hl=en&q=mvn+exit+ERRORLEVEL&meta=











A simple test to check if your version allows this - run the commands below in a bat file.

call mvn unknown
echo Exit Code = %ERRORLEVEL%









You should get a Failure with exit code 1 as below.
If it does not fail, then upgrade to a higher version of Maven in which the issue is fixed.


D:\maven-2.0.7\bin>call mvn unknown
[INFO] Scanning for projects...
[INFO] ----------------
[ERROR] BUILD FAILURE
[INFO] ----------------
[INFO] Invalid task 'unknown': you must specify a valid lifecycle phase, or a goal in the format plugin:goal or pluginGroupId:pluginArtifactId:pluginVersion:goal[INFO] ----------------
[INFO] For more information, run Maven with the -e switch
[INFO] ----------------
[INFO] Total time: < 1 second
[INFO] Finished at: Tue Mar 10 12:07:12 GMT+05:30 2009
[INFO] Final Memory: 1M/2M
[INFO] ----------------
Exit Code = 1



Update

Learnt the hard way that the call to mvn must immediately be followed by the checking of the ERRORLEVEL.

Our build.bat script measures time taken for each step like below:


time /t
call mvn install
time /t
if not "%ERRORLEVEL%" == "0" exit /b



In this case, it loses the ERRORLEVEL value from the mvn command.
Hence we need to ensure:


time /t
call mvn install
if not "%ERRORLEVEL%" == "0" exit /b
time /t