In Maven, pom.xml is the fundamental project descriptor: it defines your artifact identity, dependencies, plugins, and build behavior. This guide is for engineers who use Maven in CI/CD or local builds and want a clear, practical understanding of how POM configuration is resolved and executed.
Originally published on 2010-04-14; fully revised and updated.

What a POM is and what Maven uses it for
A Project Object Model (POM) is Maven’s configuration model stored in pom.xml. When you run a Maven goal, Maven reads this file (from the current directory unless you pass -f) and uses it to determine how to build your project.
- Project coordinates (groupId, artifactId, version)
- Packaging type (for example, jar, war, pom)
- Dependencies and dependency versions
- Build plugins and plugin configuration
- Profiles, repositories, metadata, and reporting settings
Minimal POM: the required fields
A minimal valid POM needs the project root plus these required elements: modelVersion, groupId, artifactId, and version. Together, groupId:artifactId:version form the artifact coordinates (GAV).
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
</project>Code language: HTML, XML (xml)
If you do not declare packaging, Maven uses jar by default.
Common pom.xml sections in real projects
Most production POM files add dependency management, plugin configuration, and Java/toolchain properties. A practical skeleton looks like this:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>orders-service</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>Code language: HTML, XML (xml)
Super POM, parent POM, and project inheritance
Maven applies inheritance in layers. Every project inherits from Maven’s built-in Super POM. You can also define your own parent POM to standardize settings across multiple services or modules.
| POM type | Who defines it | What it controls | Typical use |
|---|---|---|---|
| Super POM | Maven | Built-in defaults and baseline behavior | Implicit base for all Maven projects |
| Parent POM | Your org/team | Shared plugin versions, repositories, dependency management, policies | Standardizing many projects |
| Project POM | Individual project | Service-specific dependencies and build config | Application-level customization |
Commonly merged/inherited areas include dependencies, plugin lists, plugin configuration, resources, and (with matching IDs) plugin executions.
<project>
<parent>
<groupId>com.example.build</groupId>
<artifactId>platform-parent</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.services</groupId>
<artifactId>billing-service</artifactId>
<version>1.2.3</version>
</project>Code language: HTML, XML (xml)
How Maven resolves and executes POM configuration
The build configuration Maven actually executes is the effective POM (project POM + parent POM + Super POM + active profiles).
flowchart TD
A[Run mvn goal] --> B[Read project pom.xml]
B --> C[Resolve parent POM]
C --> D[Apply Super POM defaults]
D --> E[Build effective POM]
E --> F[Resolve dependencies and plugins]
F --> G[Execute lifecycle phase and goal]
# Build using pom.xml in current directory
mvn clean package
# Build with a specific POM file
mvn -f ./path/to/pom.xml clean verify
# Inspect the final merged configuration Maven sees
mvn help:effective-pomCode language: PHP (php)
Best practices and common pitfalls
- Keep coordinates stable and meaningful; changing groupId/artifactId impacts dependency consumers.
- Centralize shared versions and plugin defaults in a parent POM for consistency.
- Use
mvn help:effective-pomwhen inheritance or profiles produce unexpected behavior. - Avoid duplicating plugin versions across many child projects.
- Be explicit about repository usage and avoid unnecessary custom repositories when possible.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services — all in one place.
Explore Hospitals