Apache Maven
Build Tool & Package Manager
Apache Maven
Overview
Apache Maven is a software tool primarily used for building, dependency management, and project management of Java projects. Based on the "Convention over Configuration" philosophy, it provides standardized project structure and build lifecycle, simplifying the management of complex Java projects. Maven uses XML-based configuration files called Project Object Model (POM) to define project information, dependencies, and build settings.
Details
Architecture
The core of Maven is the Project Object Model (POM) file, which defines project information, dependencies, and build settings in XML format.
Key Features
- Standardized Directory Structure:
src/main/java,src/test/java, etc. - Dependency Management: Automatic download from central repositories
- Build Lifecycle: validate → compile → test → package → install → deploy
- Plugin Architecture: Rich plugin ecosystem
- Multi-Module Projects: Management of large-scale projects
Repository System
- Local Repository:
~/.m2/repository - Central Repository: Maven Central Repository
- Remote Repositories: Enterprise private repositories
Build Lifecycle
- validate: Validate project correctness
- compile: Compile source code
- test: Execute unit tests
- package: Create JAR/WAR files
- verify: Execute integration tests
- install: Install to local repository
- deploy: Deploy to remote repository
Convention over Configuration
Maven follows strong conventions that reduce the need for configuration:
- Standard directory layout
- Predictable build lifecycle
- Default plugin configurations
- Common project structures
Advantages & Disadvantages
Advantages
- Low Learning Curve: Easy to understand due to standardized structure
- Mature Ecosystem: Rich plugins and documentation
- IDE Support: Excellent support in IntelliJ IDEA, Eclipse, etc.
- Enterprise Adoption: Used by 67% of Java developers (2021 survey)
- CI/CD Integration: Excellent integration with Jenkins, GitLab CI, etc.
- Dependency Management: Automatic resolution of transitive dependencies
- Stability: Long track record of reliability and stability
- Large Community: Extensive community support and resources
Disadvantages
- XML Verbosity: Configuration files can become verbose
- Limited Flexibility: Customization can be difficult in some cases
- Build Speed: 2-10x slower compared to Gradle
- Complex Configuration: Advanced customization requires deep XML understanding
- Incremental Builds: Limited support compared to modern build tools
- Learning Curve for Complex Scenarios: Advanced features require significant Maven expertise
References
- Apache Maven Official Site
- Maven Central Repository
- Maven Getting Started Guide
- Maven Plugin List
- Maven vs Gradle Comparison
Code Examples
Project Creation
# Create new Maven project
mvn archetype:generate \
-DgroupId=com.example.myapp \
-DartifactId=my-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
# Create Spring Boot project
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=spring-boot-app \
-DarchetypeGroupId=org.springframework.boot \
-DarchetypeArtifactId=spring-boot-starter-parent
POM File Configuration
<?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>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Dependency Management
<!-- Dependency Management -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Excluding Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- System Dependencies -->
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
Build Lifecycle
# Clean build
mvn clean compile
# Run tests
mvn test
# Package application
mvn package
# Install to local repository
mvn install
# Deploy to remote repository
mvn deploy
# Execute up to specific phase
mvn clean test
# Package skipping tests
mvn package -DskipTests
# Offline mode
mvn -o package
# Run specific plugin goal
mvn dependency:tree
mvn dependency:analyze
Plugin Configuration
<build>
<plugins>
<!-- Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- Surefire Plugin (Test execution) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</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.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Multi-Module Projects
<!-- Parent POM -->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>core</module>
<module>web</module>
<module>api</module>
</modules>
<properties>
<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>
</project>
<!-- Child Module POM -->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>core</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
</dependencies>
</project>