How to Run Maven Build Commands from a Batch Script
Apache Maven is the standard build automation tool for Java projects, managing compilation, testing, packaging, and dependency resolution through a single pom.xml file. Running Maven commands from a Batch Script enables automated build pipelines, scheduled builds, CI/CD integration, and repeatable release processes that do not depend on manual IDE interactions.
In this guide, we will explore how to execute Maven build commands from a Batch Script, covering common build lifecycle phases, profile management, multi-module builds, and production-grade build automation.
Prerequisites
Ensure Maven is installed and on the system PATH:
@echo off
call mvn --version >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Maven not found. Install Maven and add to PATH.
echo Download from: https://maven.apache.org/download.cgi
pause
exit /b 1
)
call mvn --version
Understanding Maven Lifecycle Phases
Maven's build lifecycle is sequential. Each phase automatically executes all preceding phases:
| Phase | Action |
|---|---|
validate | Validate the project structure and POM |
compile | Compile source code |
test | Run unit tests |
package | Package compiled code (JAR, WAR) |
verify | Run integration tests |
install | Install package to local repository |
deploy | Deploy to remote repository |
Running mvn package automatically runs validate, compile, and test first.
Method 1: Basic Maven Build
@echo off
setlocal
if not exist "pom.xml" (
echo [ERROR] No pom.xml found in the current directory.
pause
exit /b 1
)
echo =============================================
echo MAVEN BUILD
echo =============================================
echo.
:: Clean and package
echo Building...
call mvn clean package -B
if %errorlevel%==0 (
echo.
echo [SUCCESS] Build complete.
echo.
echo Artifacts:
dir /b target\*.jar 2>nul
dir /b target\*.war 2>nul
) else (
echo.
echo [ERROR] Build failed.
exit /b 1
)
pause
Key Maven Flags
| Flag | Description |
|---|---|
-B | Batch mode (non-interactive, suitable for scripts) |
-q | Quiet mode (only errors) |
-X | Debug mode (verbose) |
-DskipTests | Skip test execution |
-Dmaven.test.skip=true | Skip test compilation and execution |
-P profile | Activate a build profile |
-pl module | Build specific modules only |
-T 4 | Build with 4 threads (parallel) |
-o | Offline mode (no network) |
Always use call mvn (with call) in Batch scripts. mvn.cmd is itself a Batch file, and without call, the current script terminates after Maven finishes.
Method 2: Build with Skip Tests and Profiles
@echo off
setlocal
set "profile=production"
if not exist "pom.xml" (
echo [ERROR] No pom.xml found in the current directory.
pause
exit /b 1
)
echo Building with profile: %profile% (skipping tests^)...
call mvn clean package -B -P %profile% -DskipTests
if %errorlevel%==0 (
echo [SUCCESS] Production build complete.
) else (
echo [ERROR] Build failed.
exit /b 1
)
pause
Method 3: Full Build Pipeline
A comprehensive build script with stages, timing, and logging:
@echo off
setlocal enabledelayedexpansion
if not exist "pom.xml" (
echo [ERROR] No pom.xml found in the current directory.
exit /b 1
)
for /f "tokens=2 delims==" %%T in ('wmic os get LocalDateTime /value') do set "dt=%%T"
set "logfile=build_%dt:~0,4%%dt:~4,2%%dt:~6,2%.log"
echo =============================================
echo MAVEN BUILD PIPELINE
echo %date% %time:~0,8%
echo Log: %logfile%
echo =============================================
echo.
:: Stage 1: Validate
echo [1/5] Validating...
call mvn validate -B -q >nul 2>&1
if !errorlevel! neq 0 (
echo [FAIL] Project validation failed.
exit /b 1
)
echo OK.
:: Stage 2: Compile
echo [2/5] Compiling...
call mvn compile -B -q 2>> "%logfile%"
if !errorlevel! neq 0 (
echo [FAIL] Compilation failed. See %logfile%
exit /b 1
)
echo OK.
:: Stage 3: Test
echo [3/5] Running tests...
call mvn test -B >> "%logfile%" 2>&1
set "test_result=!errorlevel!"
if !test_result! neq 0 (
echo [FAIL] Tests failed.
echo.
echo Test summary:
findstr /i "Tests run:" "%logfile%" 2>nul
echo.
set /p "continue=Continue despite test failures? (Y/N): "
if /i "!continue!" neq "Y" exit /b 1
) else (
echo OK.
)
:: Stage 4: Package
echo [4/5] Packaging...
call mvn package -B -DskipTests -q >> "%logfile%" 2>&1
if !errorlevel! neq 0 (
echo [FAIL] Packaging failed. See %logfile%
exit /b 1
)
echo OK.
:: Stage 5: Verify output
echo [5/5] Verifying artifacts...
set "artifact_found=0"
for %%F in (target\*.jar target\*.war) do (
set "artifact_found=1"
for %%S in ("%%F") do echo %%~nxF (%%~zS bytes^)
)
if !artifact_found!==0 (
echo [WARNING] No artifacts found in target\.
)
echo.
echo =============================================
echo BUILD COMPLETE
echo Log: %logfile%
echo =============================================
pause
Method 4: Multi-Module Build
For projects with multiple Maven modules:
@echo off
setlocal
if not exist "pom.xml" (
echo [ERROR] No pom.xml found in the current directory.
pause
exit /b 1
)
echo =============================================
echo MULTI-MODULE BUILD
echo =============================================
echo.
:: Build all modules with parallel threads
echo Building all modules (4 threads^)...
call mvn clean package -B -T 4
if %errorlevel%==0 (
echo [SUCCESS] All modules built.
) else (
echo [ERROR] Build failed.
exit /b 1
)
echo.
echo =============================================
echo MODULE-SPECIFIC BUILD EXAMPLES
echo =============================================
echo.
echo Build only a specific module:
echo call mvn clean package -B -pl api-module -am
echo.
echo Flags:
echo -pl = project list (specific modules^)
echo -am = also make (build dependencies of specified modules^)
pause
Method 5: Release Workflow
A Maven release preparation script:
@echo off
setlocal enabledelayedexpansion
if not exist "pom.xml" (
echo [ERROR] No pom.xml found in the current directory.
pause
exit /b 1
)
echo =============================================
echo MAVEN RELEASE WORKFLOW
echo =============================================
echo.
:: Read current version from POM
set "current="
for /f "delims=" %%V in ('call mvn help:evaluate -Dexpression^=project.version -q -DforceStdout 2^>nul') do set "current=%%V"
if not defined current (
echo [ERROR] Could not read project version from pom.xml.
pause
exit /b 1
)
echo Current version: !current!
echo.
:: Verify clean workspace
set "has_changes=0"
for /f "delims=" %%L in ('git status --porcelain 2^>nul') do set "has_changes=1"
if !has_changes!==1 (
echo [WARNING] Uncommitted changes detected:
git status --short
echo.
set /p "proceed=Continue anyway? (Y/N): "
if /i "!proceed!" neq "Y" exit /b 0
)
:: Build and verify
echo [1/3] Full build with tests...
call mvn clean verify -B
if !errorlevel! neq 0 (
echo [ABORT] Build or tests failed. Fix issues before releasing.
exit /b 1
)
:: Prompt for release version
echo.
set /p "release_ver=Enter release version (current: !current!): "
set /p "next_ver=Enter next development version (e.g., 1.3.0-SNAPSHOT): "
if not defined release_ver (
echo [ERROR] Release version is required.
exit /b 1
)
if not defined next_ver (
echo [ERROR] Next development version is required.
exit /b 1
)
:: Set version, build, and tag
echo.
echo [2/3] Setting version to !release_ver!...
call mvn versions:set -DnewVersion=!release_ver! -B -q
if !errorlevel! neq 0 (
echo [ERROR] Failed to set version.
exit /b 1
)
call mvn versions:commit -B -q
git add pom.xml **/pom.xml 2>nul
git commit -m "Release !release_ver!"
git tag -a "v!release_ver!" -m "Release !release_ver!"
:: Set next development version
echo [3/3] Setting next development version to !next_ver!...
call mvn versions:set -DnewVersion=!next_ver! -B -q
if !errorlevel! neq 0 (
echo [ERROR] Failed to set next version.
exit /b 1
)
call mvn versions:commit -B -q
git add pom.xml **/pom.xml 2>nul
git commit -m "Prepare next development cycle !next_ver!"
echo.
echo =============================================
echo RELEASE PREPARED
echo Version: !release_ver!
echo Tag: v!release_ver!
echo Next: !next_ver!
echo.
echo Push with: git push ^&^& git push --tags
echo =============================================
pause
Dependency Management
Listing Dependencies
@echo off
echo Project dependencies:
echo =====================
call mvn dependency:tree -B
pause
Checking for Updates
@echo off
echo Checking for dependency updates...
call mvn versions:display-dependency-updates -B
pause
Downloading Dependencies for Offline Use
@echo off
echo Downloading all dependencies for offline builds...
call mvn dependency:go-offline -B
echo [OK] Dependencies cached. Use "call mvn -o" for offline builds.
pause
Common Mistakes
The Wrong Way: Using mvn Without call
:: WRONG - Script terminates after Maven finishes
mvn clean package
echo This line never executes
Output Concern:
mvn.cmd is a Batch file. Running it without call causes the calling script to terminate after Maven completes. Always use call mvn in Batch scripts.
The Wrong Way: Not Using Batch Mode
:: PROBLEMATIC - Maven may prompt for input, blocking automation
mvn archetype:generate
Interactive Maven commands block automated scripts while waiting for user input. Use -B (batch mode) and provide all required parameters via -D flags.
Best Practices
- Always use
call mvn: Prevents the Batch script from terminating after Maven runs. - Use
-Bfor automation: Batch mode suppresses interactive prompts and download progress. - Use
-Tfor parallel builds: Multi-threaded builds significantly reduce build time for multi-module projects. - Log build output: Redirect to log files for debugging and audit trails.
- Use
-DskipTestswisely: Skip tests only after a separate test stage has passed.
Conclusion
Running Maven build commands from a Batch Script is accomplished by calling mvn with lifecycle phases and appropriate flags. The critical detail is using call mvn instead of plain mvn to prevent script termination. By structuring builds as staged pipelines (validate, compile, test, package), supporting profiles for environment-specific configurations, and implementing release workflows that automate version management and Git tagging, teams build professional Java build automation that runs reliably in any environment from developer workstations to CI/CD servers.