What is POM.xml?
POM (Project Object Model) is Maven's configuration file that describes:
- What your project is (coordinates, name, description)
- What it needs (dependencies)
- How to build it (plugins, goals)
- Who works on it (developers, organization)
Every Maven project has exactly one pom.xml file in the project root directory.
Complete POM Structure
<?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">
<!-- POM version (always 4.0.0) -->
<modelVersion>4.0.0</modelVersion>
<!-- ==================== PROJECT COORDINATES ==================== -->
<groupId>com.example</groupId>
<artifactId>my-application</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- ==================== PROJECT INFO ==================== -->
<name>My Application</name>
<description>A sample Maven project</description>
<url>https://github.com/example/my-application</url>
<inceptionYear>2024</inceptionYear>
<!-- ==================== PARENT POM ==================== -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<!-- ==================== PROPERTIES ==================== -->
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lombok.version>1.18.30</lombok.version>
</properties>
<!-- ==================== DEPENDENCIES ==================== -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- ==================== DEPENDENCY MANAGEMENT ==================== -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- ==================== BUILD ==================== -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- ==================== PROFILES ==================== -->
<profiles>
<profile>
<id>prod</id>
<properties>
<env>production</env>
</properties>
</profile>
</profiles>
</project>
Project Coordinates (GAV)
<!-- The unique identifier for your project -->
<groupId>com.example</groupId> <!-- Organization (reverse domain) -->
<artifactId>my-app</artifactId> <!-- Project/module name -->
<version>1.0.0-SNAPSHOT</version> <!-- Version -->
<!-- Version conventions: -->
<!-- 1.0.0-SNAPSHOT = Development version (can change) -->
<!-- 1.0.0 = Release version (immutable) -->
<!-- 1.0.0-RC1 = Release candidate -->
<!-- 1.0.0-M1 = Milestone release -->
<!-- Packaging types: -->
<packaging>jar</packaging> <!-- Default: Java library/app -->
<packaging>war</packaging> <!-- Web application -->
<packaging>pom</packaging> <!-- Parent/BOM (no code) -->
<packaging>ear</packaging> <!-- Enterprise archive -->
Properties
<properties>
<!-- Java version -->
<java.version>21</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<!-- Encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Dependency versions (single place to manage) -->
<spring.version>6.1.0</spring.version>
<junit.version>5.10.0</junit.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<!-- Using properties: -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version> <!-- References property -->
</dependency>
<!-- Built-in properties: -->
<!-- ${project.basedir} - Project root directory -->
<!-- ${project.version} - Project version -->
<!-- ${project.artifactId} - Artifact ID -->
<!-- ${env.JAVA_HOME} - Environment variable -->
Parent POM
<!-- Inherit configuration from a parent POM -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- Empty = look in repository, not filesystem -->
</parent>
<!-- What parent provides: -->
<!-- - Managed dependency versions -->
<!-- - Plugin configurations -->
<!-- - Default properties -->
<!-- - Resource filtering -->
<!-- You can then omit versions: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- No version needed - inherited from parent! -->
</dependency>
Build Section
<build>
<!-- Final artifact name -->
<finalName>my-app</finalName>
<!-- Source directories (usually not needed - conventions) -->
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<!-- Resources (non-Java files to include) -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> <!-- Replace ${} placeholders -->
</resource>
</resources>
<!-- Plugins -->
<plugins>
<!-- Compiler plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
<!-- Surefire plugin (runs tests) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<!-- JAR plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Profiles
<profiles>
<!-- Development profile -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<!-- Production profile -->
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>prod-logging</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
<!-- Activate profile: mvn package -Pprod -->
Multi-Module Projects
<!-- Parent pom.xml -->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging> <!-- Must be 'pom' for parent -->
<modules>
<module>core</module>
<module>api</module>
<module>web</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- Manage versions for all modules -->
</dependencies>
</dependencyManagement>
</project>
<!-- Child module pom.xml (e.g., core/pom.xml) -->
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>core</artifactId>
<!-- groupId and version inherited from parent -->
</project>
Summary
- GAV: groupId:artifactId:version uniquely identifies artifacts
- Properties: Variables for versions and settings
- Parent: Inherit configuration from another POM
- Dependencies: Libraries your project needs
- DependencyManagement: Manage versions without adding dependencies
- Build: Plugins and build configuration
- Profiles: Environment-specific configuration
- Modules: Multi-module project structure