What Is the Parent POM in Jenkins? Understanding Maven Inheritance in jenkinsci/jenkins
The parent POM in Jenkins serves as the centralized configuration anchor for the entire multi-module Maven build, defining shared versions, plugin management, and build rules that all sub-modules automatically inherit.
Jenkins is architected as a multi-module Maven project within the jenkinsci/jenkins repository. The root pom.xml—the parent POM—acts as the single source of truth, ensuring that components such as the core library, WAR file, and CLI tool all build with identical dependency versions and consistent Maven settings.
Centralized Version Management
In pom.xml lines 75-78, the parent defines critical version properties including <revision> and <changelist>. These properties establish the baseline version for the entire project:
<revision>2.576</revision>
<changelist>-SNAPSHOT</changelist>
Every child module references these properties using ${revision} and ${changelist}, guaranteeing that a single property change propagates consistently across the entire codebase. The parent also declares the bundled Remoting version as ${remoting.version} (set to 3384.v60d89463d9e0 at lines 89-91), which modules reference without hardcoding specific version numbers.
Plugin and Dependency Version Control
The parent POM prevents "dependency drift" through centralized <pluginManagement> and <dependencyManagement> sections (lines 37-91). By pinning exact versions of Maven plugins such as maven-compiler-plugin, spotless-maven-plugin, and bridge-method-injector in one location, all modules use identical build tools without declaring versions locally.
This inheritance mechanism ensures that when the Jenkins project upgrades a plugin version, the change applies immediately to every module—core, war, cli, and others—without requiring individual POM edits.
Shared Build Configuration
Common build resources and enforcement rules are defined once in the parent (lines 124-140 and 442-458) and inherited by all children. This includes:
- Default goals:
<defaultGoal>install</defaultGoal> - Resource filtering: Standard resource directories and filtering rules
- Maven Enforcer: Rules for banned dependencies and required Maven versions
Child modules automatically adopt these standards, focusing their own pom.xml files on module-specific dependencies and source code rather than repetitive build boilerplate.
Repository and SCM Declarations
Rather than duplicating repository metadata in every module, the parent POM declares the public Jenkins Maven repository and SCM connections (lines 110-118). This eliminates redundancy and ensures that mvn commands execute against the correct artifact repositories regardless of which subdirectory a developer builds from.
Module Aggregation
The <modules> section (lines 52-60) enumerates all sub-projects including core, war, cli, and others. This aggregation allows Maven to calculate the correct build order when you run commands from the repository root, ensuring that dependencies compile before the modules that require them.
Profile Management for CI/CD
CI-specific profiles such as yarn-execution, debug, and release are defined centrally (lines 274-381) and become available to every module. These profiles handle Node.js integration, GPG signing for releases, and debug flags without requiring each child POM to redefine the configuration.
How Child Modules Inherit from the Parent
Each child module declares its lineage through a <parent> block. For example, in core/pom.xml, the module identifies the parent as org.jenkins-ci.main:jenkins-parent, inheriting all managed versions and build configurations:
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-parent</artifactId>
<version>${revision}${changelist}</version>
</parent>
This inheritance chain extends further: the root pom.xml itself declares a parent pointing to the jenkins BOM (Bill of Materials) at lines 28-33, establishing a hierarchical version management strategy.
Practical Examples of Parent POM Inheritance
Inheriting Compiler Configuration Without Version Declarations
Child modules do not specify plugin versions for standard build tools:
<!-- In core/pom.xml -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- Version inherited from parent's pluginManagement -->
</plugin>
</plugins>
</build>
Referencing Parent-Defined Properties
Modules consume the Remoting version defined centrally:
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>remoting</artifactId>
<version>${remoting.version}</version>
</dependency>
The ${remoting.version} property resolves to 3384.v60d89463d9e0 as defined in the root pom.xml.
Leveraging Plugin Management
Adding a plugin like build-helper-maven-plugin requires no version declaration:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<!-- Version supplied by parent POM -->
</plugin>
</plugins>
</build>
Key Files in the Jenkins Maven Structure
pom.xml(root): Defines the parent POM, shared properties, plugin versions, modules, and profiles.core/pom.xml: Jenkins core module inheriting all parent settings.war/pom.xml: Constructs thejenkins.warartifact using parent-defined versions.cli/pom.xml: Command-line interface module leveraging parent's dependency management.bom/pom.xml: Bill of Materials providing curated dependency versions for downstream projects.
Summary
- The parent POM in
jenkinsci/jenkinsis the rootpom.xmlthat centralizes version properties, plugin management, and build configuration. - It defines
<revision>and<changelist>properties (lines 75-78) that all modules reference for consistent versioning. <pluginManagement>and<dependencyManagement>sections (lines 37-91) prevent version drift across the multi-module project.- The
<modules>section (lines 52-60) aggregates sub-projects likecore,war, andclifor unified builds. - Child modules inherit settings via
<parent>declarations, eliminating duplicate configuration incore/pom.xml,war/pom.xml, and other sub-modules. - CI-specific profiles and repository definitions are maintained centrally, ensuring consistent build behavior across all components.
Frequently Asked Questions
How does a child module override a plugin version defined in the parent POM?
A child module can declare a specific <version> within its <plugin> declaration, which takes precedence over the parent's <pluginManagement> configuration. However, the Jenkins project typically discourages this to maintain build consistency across the entire codebase.
What is the relationship between the root pom.xml and the bom/pom.xml?
The root pom.xml serves as the immediate parent for Jenkins modules, while bom/pom.xml (Bill of Materials) provides a curated set of dependency versions often imported as a managed dependency. The root POM may itself inherit from or import this BOM (lines 28-33 reference the grand-parent jenkins artifact), creating a layered version management strategy that benefits both internal modules and external Jenkins plugins.
Where is the Jenkins version number actually defined?
The version is defined in the <properties> section of the root pom.xml at lines 75-78, specifically through the <revision> and <changelist> properties. During the build, these concatenate to form the full version identifier (e.g., 2.576-SNAPSHOT) used throughout all modules.
Can I build a single module without building the entire Jenkins project?
Yes. While the parent POM aggregates modules for full builds, you can navigate to a specific module directory like core/ or cli/ and run mvn install. The child POM inherits sufficient configuration from the parent (accessible in your local Maven repository) to build independently, though initial builds may require the parent POM to be installed first.
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 →