Apache Maven
ビルドツール・パッケージマネージャー
Apache Maven
概要
Apache Mavenは、主にJavaプロジェクトのビルド、依存関係管理、プロジェクト管理を行うためのソフトウェアツールです。「Convention over Configuration(設定より規約)」の哲学に基づき、標準化されたプロジェクト構造とビルドライフサイクルを提供し、複雑なJavaプロジェクトの管理を簡素化します。
詳細
アーキテクチャ
Mavenの中核にあるのはProject Object Model(POM)ファイルで、これはXML形式でプロジェクトの情報、依存関係、ビルド設定を定義します。
主要特徴
- 標準化されたディレクトリ構造:
src/main/java、src/test/javaなど - 依存関係管理: 中央リポジトリからの自動ダウンロード
- ビルドライフサイクル: validate → compile → test → package → install → deploy
- プラグインアーキテクチャ: 豊富なプラグインエコシステム
- マルチモジュールプロジェクト: 大規模プロジェクトの管理
リポジトリシステム
- ローカルリポジトリ:
~/.m2/repository - 中央リポジトリ: Maven Central Repository
- リモートリポジトリ: 企業内プライベートリポジトリ
ビルドライフサイクル
- validate: プロジェクトの妥当性確認
- compile: ソースコードのコンパイル
- test: 単体テストの実行
- package: JAR/WARファイルの作成
- verify: 統合テストの実行
- install: ローカルリポジトリへのインストール
- deploy: リモートリポジトリへのデプロイ
メリット・デメリット
メリット
- 学習コストが低い: 標準化された構造で理解しやすい
- 成熟したエコシステム: 豊富なプラグインとドキュメント
- IDE サポート: IntelliJ IDEA、Eclipse などでの優れたサポート
- 企業での採用率: 67% の Java 開発者が使用(2021年調査)
- CI/CD 統合: Jenkins、GitLab CI などとの優れた統合
- 依存関係管理: トランジティブ依存関係の自動解決
- 安定性: 長年にわたる実績と安定性
デメリット
- XML の冗長性: 設定ファイルが冗長になりがち
- 柔軟性の制限: カスタマイズが困難な場合がある
- ビルド速度: Gradle と比較して 2-10 倍遅い
- 複雑な設定: 高度なカスタマイズには XML の深い理解が必要
- インクリメンタルビルド: 限定的なサポート
参考ページ
書き方の例
プロジェクトの作成
# Maven プロジェクトの新規作成
mvn archetype:generate \
-DgroupId=com.example.myapp \
-DartifactId=my-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
# Spring Boot プロジェクトの作成
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=spring-boot-app \
-DarchetypeGroupId=org.springframework.boot \
-DarchetypeArtifactId=spring-boot-starter-parent
POMファイルの設定
<?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>
依存関係の管理
<!-- 依存関係管理 -->
<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>
<!-- 依存関係の除外 -->
<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>
<!-- システム依存関係 -->
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
ビルドライフサイクル
# クリーンビルド
mvn clean compile
# テストの実行
mvn test
# パッケージング
mvn package
# ローカルリポジトリへのインストール
mvn install
# リモートリポジトリへのデプロイ
mvn deploy
# 特定のフェーズまで実行
mvn clean test
# テストをスキップしてパッケージング
mvn package -DskipTests
# オフラインモード
mvn -o package
プラグインの使用
<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 (テスト実行) -->
<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>
マルチモジュールプロジェクト
<!-- 親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>
</project>
<!-- 子モジュール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>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>