How to Customize the Jenkins Build Process with Maven: A Complete Guide
Jenkins provides a dedicated Maven builder (hudson.tasks.Maven) that lets you customize builds through executable selection, JVM options, settings files, and automatic environment variable injection.
Customizing the Jenkins build process with Maven is essential for teams requiring fine-grained control over their CI/CD pipelines. According to the jenkinsci/jenkins source code, the hudson.tasks.Maven class implements a flexible builder that manages everything from tool resolution to argument construction. Understanding these internals allows you to optimize builds for performance, isolation, and reproducibility.
Core Components of the Maven Build System
The Maven integration relies on three primary classes working together:
| Component | Source File | Purpose |
|---|---|---|
| Maven Builder | core/src/main/java/hudson/tasks/Maven.java |
The build step that launches Maven, parses targets, and assembles command lines. |
| MavenInstallation | Inner class of Maven.java |
Represents a Maven installation, resolves the executable path, and configures environment variables like M2_HOME and PATH+MAVEN. |
| GlobalMavenConfig | core/src/main/java/jenkins/mvn/GlobalMavenConfig.java |
Supplies default settings.xml and global-settings.xml paths that can be overridden per-job. |
How the Maven Builder Executes Your Build
The perform method in hudson/tasks/Maven.java orchestrates execution through six distinct phases:
-
Target Parsing – The
targetsfield splits on the pipe character (|), allowing multiple Maven invocations in a single build step (e.g.,"clean install | site"). -
Executable Resolution – If
mavenNamereferences aMavenInstallation, Jenkins callsMavenInstallation.getExecutableto locate the binary. If unconfigured,DecideDefaultMavenCommandinspects the workspace forpom.xmlto choose betweenmvnormaven. -
Settings Handling – Unless the user passes
-sor-gsarguments, the builder injects paths fromSettingsProvider.getSettingsRemotePathandGlobalSettingsProvider.getSettingsRemotePath. -
Environment Injection – When
injectBuildVariablesistrue(default), Jenkins automatically adds-Darguments for all build variables before appending custom properties from thepropertiesfield. -
Private Repository Isolation – Setting
usePrivateRepositorytotrueadds-Dmaven.repo.local=$WORKSPACE/.repositoryto isolate dependencies per build. -
Process Launch – The assembled
ArgumentListBuilderis passed toLauncher.launch(). On Unix, the command executes directly; on Windows, it converts to a batch command.
Customization Points and Configuration Fields
You can configure these fields in the job UI or through Pipeline steps:
| Field | Control | Example |
|---|---|---|
targets |
Maven goals and CLI options | "clean package -DskipTests" |
mavenName |
Reference to a MavenInstallation |
"Maven-3.9" |
pom |
Relative path to POM file | "submodule/pom.xml" |
properties |
Additional -D properties (newline-separated) |
"env=prod\nopt=true" |
jvmOptions |
Memory and JVM settings (MAVEN_OPTS) |
"-Xmx2g -XX:+UseG1GC" |
usePrivateRepository |
Boolean for isolated local repos | true |
settings / globalSettings |
Custom XML configuration files | FilePathSettingsProvider instance |
injectBuildVariables |
Automatic -D variable injection |
true (default) |
Configuring Maven Installations Globally
Before customizing individual jobs, define your Maven tools:
- Navigate to Manage Jenkins → Global Tool Configuration → Maven.
- Add a
MavenInstallationspecifying the name andMAVEN_HOMEdirectory, or enable the automatic installer (implemented in the inner classMavenInstaller). - The
Maven.DescriptorImplclass persists these configurations via thesetInstallationsmethod.
Jenkins stores this metadata to resolve executables via MavenInstallation.getExecutable at runtime.
Using Maven in Jenkins Pipelines
For Pipeline projects, use the tools directive to expose the installation, then invoke Maven directly or through the builder:
pipeline {
agent any
tools {
maven 'Maven-3.9' // Must match a configured MavenInstallation name
}
environment {
APP_ENV = 'production'
}
stages {
stage('Build') {
steps {
sh '''
mvn clean install \
-Dmaven.repo.local=$WORKSPACE/.repository \
-Dapp.env=$APP_ENV
'''
}
}
}
}
Alternatively, the withMaven step wraps the same hudson.tasks.Maven logic and accepts parameters like mavenSettingsConfig and injectBuildVariables: false for advanced customization.
Advanced Customization Scenarios
| Scenario | Implementation |
|---|---|
| Version-per-branch builds | Define separate MavenInstallation entries (e.g., Maven-3.8, Maven-3.9) and parameterize the mavenName field. |
| Custom settings.xml per job | Configure the Settings file option to use a FilePathSettingsProvider, which overrides GlobalMavenConfig defaults for that specific build. |
| Disable variable injection | Set injectBuildVariables to false in the UI or Pipeline to prevent automatic -D argument generation. |
| Chained Maven commands | Use pipe syntax in targets: `"clean deploy |
Summary
- The
hudson.tasks.Mavenclass is the core engine for Maven integration, handling command assembly in itsperformmethod. - Configure
MavenInstallationinstances globally to manage multiple Maven versions and automatic downloads. - Use
injectBuildVariablesto automatically pass Jenkins environment variables as Maven properties, or disable it for stricter control. - Enable
usePrivateRepositoryto ensure build isolation through per-workspace local repositories. - Override global settings via
GlobalMavenConfigor per-job providers likeFilePathSettingsProvider.
Frequently Asked Questions
How do I specify a custom Maven version for a specific job?
Define multiple MavenInstallation entries in Global Tool Configuration, then reference the specific installation name in your job configuration via the mavenName field. In Pipeline, use the tools { maven 'InstallationName' } block.
Where does Jenkins find the settings.xml file?
By default, Jenkins reads paths from GlobalMavenConfig.java. You can override this per-job by selecting a custom provider (such as FilePathSettingsProvider) in the build step configuration, or by passing explicit -s and -gs arguments in your targets.
Can I run multiple Maven commands in a single build step?
Yes. Enter multiple commands separated by the pipe character (|) in the Goals and options field. Jenkins executes them sequentially while maintaining the same environment variables and working directory.
How do I disable automatic injection of Jenkins variables?
Set the injectBuildVariables field to false in the Maven build step configuration. In Pipeline syntax using the withMaven step, specify injectBuildVariables: false to prevent the builder from automatically passing build parameters as system properties.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →