Understanding pom.xml in Maven: A Beginner-Friendly Guide

Anju
5 min readOct 7, 2024

If you’ve ever worked on a Maven-based Java project, chances are you’ve come across the pom.xml file. This is Maven’s Project Object Model file and is essentially the backbone of any Maven project. It contains important information about your project, configuration details, dependencies, and build steps. In this blog, we'll break down a simple pom.xml file and explain each part to help you understand its structure.

Here’s a sample pom.xml file that we’ll dissect:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>example-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Example App</name>
<description>A simple example Maven project</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<jacoco.version>0.8.10</jacoco.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<!-- Distribution Management Section -->
<distributionManagement>
<repository>
<id>dummy-repo</id>
<name>dummy-maven-repo</name>
<url>https://dummy.repo.com/maven-repo</url>
</repository>
<snapshotRepository>
<id>dummy-repo</id>
<name>dummy-maven-repo</name>
<url>https://dummy.repo.com/maven-snapshot-repo</url>
</snapshotRepository>
</distributionManagement>

<!-- Repositories Section -->
<repositories>
<repository>
<id>dummy-repo</id>
<name>dummy-maven-repo</name>
<url>https://dummy.repo.com/maven-repo</url>
</repository>
</repositories>

<!-- Dependency Management Section -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Breaking Down the pom.xml

  1. XML Declaration and Project Element
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  • XML Declaration: This line defines the XML version and character encoding (UTF-8) for the file. It’s standard for any XML document.
  • <project> tag: This is the root element of the pom.xml file. It contains all project-specific information, dependencies, and build configurations.

2. Model Version

<modelVersion>4.0.0</modelVersion>

This tag specifies the version of the POM model you’re using. The 4.0.0 version is the standard and the most commonly used in Maven projects today.

3. Project Coordinates (groupId, artifactId, version)

<groupId>com.example</groupId>
<artifactId>example-app</artifactId>
<version>1.0.0-SNAPSHOT</version>

These elements uniquely identify your project:

  • groupId: This is usually the company or organization’s domain name in reverse (e.g., com.example), to ensure global uniqueness.
  • artifactId: The name of your project or module.
  • version: The project version. The -SNAPSHOT suffix indicates this is a development version, allowing frequent updates.

4. Packaging Type

<packaging>pom</packaging>

This defines the project’s packaging type. In our example, it’s pom because this is a parent project or aggregator POM (used for multi-module projects). Other common values are jar, war, or ear.

5. Project Metadata (Name and Description)

<name>Example App</name>
<description>A simple example Maven project</description>

These tags provide basic metadata about your project:

  • <name>: A human-readable name for the project.
  • <description>: A brief description that can be used in documentation or project listing.

6. Parent POM

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
</parent>

The parent section allows this project to inherit configurations, dependencies, and plugins from another POM (in this case, Spring Boot’s spring-boot-starter-parent POM). This makes project setup easier because common dependencies and configurations don’t need to be defined in every project.

7. Properties

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<jacoco.version>0.8.10</jacoco.version>
</properties>

The <properties> section defines variables that can be reused throughout the pom.xml file. They make your POM more readable and maintainable. In this example:

  • project.build.sourceEncoding: Sets the encoding for your source files.
  • java.version: Sets the Java version to 17.
  • jacoco.version: Defines the version of JaCoCo, a tool for code coverage.

8. Dependencies

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

This section lists all the external libraries (dependencies) your project needs. Each <dependency> tag contains:

  • groupId: Identifies the organization or group that provides the dependency.
  • artifactId: The name of the dependency.
  • version: The version of the library.
  • scope: Optional. The scope of the dependency, such as test (only used during testing).

In this example:

  • We are using spring-boot-starter-web for building a web application.
  • The PostgreSQL database driver is included.
  • JUnit is added for testing purposes (with the test scope).

9. distributionManagement Section

This section controls how your artifacts are distributed, especially when deploying them to a repository like Artifactory or Nexus.

<distributionManagement>
<repository>
<id>dummy-repo</id>
<name>dummy-maven-repo</name>
<url>https://dummy.repo.com/maven-repo</url>
</repository>
<snapshotRepository>
<id>dummy-repo</id>
<name>dummy-maven-repo</name>
<url>https://dummy.repo.com/maven-snapshot-repo</url>
</snapshotRepository>
</distributionManagement>
  • Why it’s useful: When your project needs to be shared or deployed to a repository (for example, for other teams to use), this section ensures that your artifacts are correctly uploaded to the specified repository.
  • Key elements:
  • repository: Defines where the final build artifacts (non-snapshot versions) will be stored.
  • snapshotRepository: Used specifically for snapshot versions, which are continuously updated during development.

10. repositories Section

This section tells Maven where to look for dependencies when building your project. By default, Maven uses the Maven Central repository, but you might need to specify additional or internal repositories.

<repositories>
<repository>
<id>dummy-repo</id>
<name>dummy-maven-repo</name>
<url>https://dummy.repo.com/maven-repo</url>
</repository>
</repositories>
  • Why it’s useful: If your project relies on dependencies that are hosted in private repositories (such as Artifactory or Nexus), this section ensures that Maven knows where to find them.
  • Key elements:
  • id: This is a unique identifier for the repository.
  • url: This is the location where Maven should look for dependencies.

11. dependencyManagement Section

This section allows for centralized management of dependency versions. It doesn’t automatically pull dependencies into your project but instead provides a reference that simplifies adding dependencies later.

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
  • Why it’s useful: When working with a large set of related dependencies (like Spring Cloud), this ensures consistency in versioning and reduces the need to manually specify versions for each dependency in different modules.
  • Key elements:
  • groupId and artifactId: These identify the spring-cloud-dependencies BOM (Bill of Materials) for version management.
  • version: This is a placeholder (${spring-cloud.version}), which you can define in the properties section for easier version updates.
  • type and scope: Specifies that this is a POM file being imported, which manages several related dependencies.

12. Build Section

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>

The <build> section defines how the project will be compiled and built. In this case:

  • Maven Compiler Plugin: This plugin ensures that your project is compiled with the correct Java version (set to 17 via the ${java.version} property).
  • Plugins: Plugins are used to add functionality during the build process. Maven’s plugin system is very flexible, allowing tasks such as compiling, testing, and deploying to be automated.

Key Takeaways

  1. Project Identification: The groupId, artifactId, and version are like the DNA of your project and ensure it's uniquely identifiable in Maven repositories.
  2. Dependency Management: The pom.xml helps you manage external libraries easily by automatically resolving and downloading them.
  3. dependencyManagement: Centralized dependency version management, which is crucial when dealing with multiple related libraries (like Spring Cloud).
  4. distributionManagement: Defines how and where your project’s artifacts are distributed, ensuring that other teams or systems can easily access your builds.
  5. repositories: Specifies where Maven should fetch dependencies, which is useful when you have internal or private dependencies.
  6. Build Configuration: The build section and plugins enable custom configurations for how your project is built and packaged.
  7. Inheritance with Parent POM: Maven’s inheritance model allows projects to reuse common configurations from a parent POM, reducing redundancy.

Conclusion

The pom.xml is the core of a Maven project, acting as a blueprint that controls the build process, dependency management, and project configurations. By understanding the key elements of a POM, you can better navigate

Acknowledgement

--

--

Anju
Anju

Written by Anju

A DevOps engineer who loves automating everything (almost), exploring new places, and finding peace in nature. Always looking for the next adventure!

No responses yet