Appearance
Maven Cheatsheet
Overview
Apache Maven is a build automation and project management tool primarily used for Java projects. It uses XML-based configuration files (POM) and follows the convention-over-configuration principle.
Installation
Package Managers
bash
# macOS
brew install maven
# Ubuntu/Debian
sudo apt install maven
# CentOS/RHEL
sudo yum install maven
# Windows (Chocolatey)
choco install maven
# Manual installation
wget https://archive.apache.org/dist/maven/maven-3/3.9.0/binaries/apache-maven-3.9.0-bin.tar.gz
tar -xzf apache-maven-3.9.0-bin.tar.gz
export PATH=$PATH:/path/to/apache-maven-3.9.0/bin
Verification
bash
mvn --version
mvn -v
Project Structure
Standard Directory Layout
project/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ ├── resources/
│ │ └── webapp/
│ └── test/
│ ├── java/
│ └── resources/
├── target/
└── README.md
Basic POM (pom.xml)
Minimal POM
xml
<?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>my-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>My Application</name>
<description>A sample Maven project</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Complete POM Example
xml
<?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>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>My Application</name>
<description>A comprehensive Maven project example</description>
<url>https://github.com/example/my-app</url>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.3.21</spring.version>
<junit.version>5.8.2</junit.version>
</properties>
<dependencies>
<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
</plugin>
</plugins>
</build>
</project>
Dependencies
Dependency Scopes
xml
<dependencies>
<!-- Compile scope (default) -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- Test scope -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- Runtime scope -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
<scope>runtime</scope>
</dependency>
<!-- Provided scope -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- System scope -->
<dependency>
<groupId>com.example</groupId>
<artifactId>custom-lib</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/custom-lib.jar</systemPath>
</dependency>
</dependencies>
Dependency Management
xml
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Version management -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
</dependencyManagement>
Exclusions
xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.21</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Build Lifecycle
Default Lifecycle Phases
bash
# Validate
mvn validate
# Compile
mvn compile
# Test
mvn test
# Package
mvn package
# Integration test
mvn integration-test
# Verify
mvn verify
# Install
mvn install
# Deploy
mvn deploy
# Clean
mvn clean
Common Phase Combinations
bash
# Clean and compile
mvn clean compile
# Clean and package
mvn clean package
# Clean, test, and install
mvn clean test install
# Skip tests
mvn clean package -DskipTests
# Skip test compilation
mvn clean package -Dmaven.test.skip=true
Plugins
Core Plugins
xml
<build>
<plugins>
<!-- Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- Surefire Plugin (Unit Tests) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<includes>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>
<!-- Failsafe Plugin (Integration Tests) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M7</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- JAR Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Popular Third-Party Plugins
xml
<!-- Spring Boot Plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Shade Plugin (Fat JAR) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<!-- JaCoCo Plugin (Code Coverage) -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Docker Plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
<tag>${project.version}</tag>
</configuration>
</plugin>
Profiles
Environment Profiles
xml
<profiles>
<!-- Development Profile -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<database.url>jdbc:h2:mem:testdb</database.url>
<log.level>DEBUG</log.level>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.212</version>
</dependency>
</dependencies>
</profile>
<!-- Production Profile -->
<profile>
<id>prod</id>
<properties>
<database.url>jdbc:mysql://prod-server:3306/mydb</database.url>
<log.level>INFO</log.level>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
</dependencies>
</profile>
<!-- Testing Profile -->
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Activation Conditions
xml
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<!-- Windows-specific configuration -->
</profile>
<profile>
<id>java11</id>
<activation>
<jdk>11</jdk>
</activation>
<!-- Java 11 specific configuration -->
</profile>
<profile>
<id>property-based</id>
<activation>
<property>
<name>environment</name>
<value>production</value>
</property>
</activation>
<!-- Activated when -Denvironment=production -->
</profile>
Multi-Module Projects
Parent POM
xml
<?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>my-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>My Parent Project</name>
<modules>
<module>core</module>
<module>web</module>
<module>api</module>
</modules>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.3.21</spring.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Child Module POM
xml
<?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>
<parent>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>core</artifactId>
<packaging>jar</packaging>
<name>Core Module</name>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Command Line Usage
Basic Commands
bash
# Create new project
mvn archetype:generate -DgroupId=com.example -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
# Compile
mvn compile
# Test
mvn test
# Package
mvn package
# Install to local repository
mvn install
# Deploy to remote repository
mvn deploy
# Clean
mvn clean
Advanced Options
bash
# Activate profile
mvn clean package -Pprod
# Set properties
mvn clean package -Denvironment=production -Dlog.level=INFO
# Skip tests
mvn clean package -DskipTests
# Offline mode
mvn clean package -o
# Debug mode
mvn clean package -X
# Quiet mode
mvn clean package -q
# Update snapshots
mvn clean package -U
# Parallel builds
mvn clean package -T 4
# Resume from specific module
mvn clean package -rf :web-module
Dependency Commands
bash
# Show dependency tree
mvn dependency:tree
# Show effective POM
mvn help:effective-pom
# Show effective settings
mvn help:effective-settings
# Analyze dependencies
mvn dependency:analyze
# Copy dependencies
mvn dependency:copy-dependencies
# Resolve dependencies
mvn dependency:resolve
# Show dependency sources
mvn dependency:sources
# Show dependency javadocs
mvn dependency:resolve -Dclassifier=javadoc
Settings and Configuration
settings.xml (~/.m2/settings.xml)
xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>${user.home}/.m2/repository</localRepository>
<servers>
<server>
<id>nexus</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
<mirrors>
<mirror>
<id>central-mirror</id>
<name>Central Repository Mirror</name>
<url>https://repo1.maven.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<url>http://localhost:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
Repository Configuration
xml
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo1.maven.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
Best Practices
POM Organization
xml
<!-- Order elements consistently -->
<project>
<!-- Project coordinates -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<!-- Project information -->
<name>My Application</name>
<description>Application description</description>
<url>https://github.com/example/my-app</url>
<!-- Properties -->
<properties>
<!-- Version properties -->
</properties>
<!-- Dependency management -->
<dependencyManagement>
<!-- BOM imports -->
</dependencyManagement>
<!-- Dependencies -->
<dependencies>
<!-- Dependencies -->
</dependencies>
<!-- Build configuration -->
<build>
<!-- Build configuration -->
</build>
<!-- Profiles -->
<profiles>
<!-- Profiles -->
</profiles>
</project>
Version Management
xml
<properties>
<!-- Use properties for versions -->
<spring.version>5.3.21</spring.version>
<junit.version>5.8.2</junit.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<!-- Use BOM for related dependencies -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Troubleshooting
Common Issues
bash
# Clear local repository
rm -rf ~/.m2/repository
# Force update snapshots
mvn clean package -U
# Debug dependency resolution
mvn dependency:tree -Dverbose
# Check for dependency conflicts
mvn dependency:analyze
# Validate POM
mvn validate
# Check effective POM
mvn help:effective-pom
Debug Mode
bash
# Enable debug output
mvn clean package -X
# Show version information
mvn --version
# Show help
mvn help:help
Resources
- Official Documentation: maven.apache.org
- POM Reference: maven.apache.org/pom.html
- Plugin List: maven.apache.org/plugins
- Central Repository: search.maven.org