第1章
構成管理入門  

第2章
Subversionによるバージョン管理入門

第3章
Subversionベストプラクティス

第4章
Maven2によるビルド入門

第5章
Maven2ベストプラクティスリリースの自動化

第6章
リリースの自動化

Appendix
Maven 2はまり道


※WEB+DB PRESS Vol.39掲載の記事を載せています。

第4章 Maven2によるビルド入門

Authors:YAMAMOTO Ryuzo

まずは試してみよう

それでは新しいWebアプリケーションを作成してみましょう。
下記のコマンドを適当なディレクトリで実行します。コマンドの内容についてはのちほど説明しますので、まずはコマンドを実行してみてください。

> mvn archetype:create -DgroupId=jp.gihyo -Dartifac
tId=webdb-webapp -DarchetypeArtifactId=maven-archet
ype-webapp (実際は1行)
…
Downloading:…
…
[INFO] BUILD SUCCESSFUL
…

完了すると、「webdb-webapp」というディレクトリにWebアプリケーションのひな形が作成されます。 このディレクトリに移動して、試しに次のコマンドを実行してみてください。

> mvn package
…
[INFO] BUILD SUCCESSFUL
…

すると、「target」というディレクトリの中に「webdb-webapp.war」というファイルが作成されていますね。 そう、先ほど作成したプロジェクトの成果物ができているのです。どうです? すごくないですか?! プロジェクトを作成したばかりのこの時点で、すでに最終的な成果物「WARファイル」を作成する手順はもう できてしまっています。
もちろん、プロジェクトを作成しただけで中身のプログラミングはまったく行っていませんので、 何もできないWebアプリケーションです(「HelloWorld !」を表示するだけです)。

リモートリポジトリ、ローカルリポジトリ

先ほどの新しいプロジェクトを作成するコマンドを実行した際に、「Downloading:...」が非常にたくさん 表示されたことと思います。このとき、必要な機能(プラグイン)や依存ライブラリのダウンロードが行わ れていました。
Maven 2本体はとても小さな機能のみしか持たず、ある機能(プラグイン)や依存ライブラリが 必要になったときに初めて、「リモートリポジトリ」と呼ばれるWeb上のリポジトリから「ローカルリポジ トリ」と呼ばれるローカルのディレクトリにダウンロードしてきます。

リモートリポジトリは、依存ライブラリなどの配布を目的としたサイトです。 Maven2の公式リポジトリhttp://repo1.maven.org/maven2/は「セントラルリポジトリ」と呼ばれており、 ここには、さまざまなライブラリ(JARなど)が登録されています。 リモートリポジトリにはセントラルリポジトリ以外のものを利用することができ、たとえばCodehaus やSeasar2プロジェクト独自のリポジトリ、次章で説明する「社内リポジトリ(インハウスリポジトリ)」 などもリモートリポジトリの1つです(図2)。

図2 リモートリポジトリとローカルリポジトリ


ローカルリポジトリは、Maven2が使用するプラグインやライブラリ、私たちのプロジェクトで使用する依存 ライブラリが保存されていきます。 ローカルリポジトリはデフォルトで、次のディレクトリになります。
ユーザのホームディレクトリ/.m2/repository
(例:C:\Document And Settings\yamamoto\.m2\
repositories)

POM

先ほど作成されたディレクトリwebdb-webappの中に、「pom.xml」というXMLファイルが作成されています。 Maven 2で最も重要なのが、このpom.xml(プロジェクト定義ファイル)です(リスト3)。

●リスト3 pom.xmlの例
<project xmlns="http://maven.apache.org/POM/4.0.0"…>
<modelVersion>4.0.0</modelVersion>
<groupId>jp.gihyo</groupId> ←プロジェクトグループのID
<artifactId>webdb-utils</artifactId>←プロジェクトのID
<packaging>jar</packaging>     ←作成する成果物の種類(JAR,WAR,EARなど)
<version>1.0.1</version>      ←プロジェクトのバージョン
<name>Gihyo Web Utils</name>    ←プロジェクトの表示名
<url>http://gihyo.jp</url>     ←プロジェクトのサイトURL
<dependencies>           ←プロジェクトが依存するライブラリ情報
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>jar</scope>
</dependencies>
</dependencies>
</project>


「POM = Project Object Model」には、組織、開発者、課題管理、ソースコード管理、 ビルド方法、依存ライブラリなど、プロジェクトに関するさまざまな情報が含まれています。 pom.xmlを理解すれば、Maven 2のほとんどを理解したと言っても過言ではありません。
pom.xml については、公式サイトの「POMReference」(注3) にリファレンスがあります。
pom.xmlの要素の中でgroupId、artifactIdが非常に重要であり、プロジェクトの成果物(JAR、WAR、EARなど )の名前やリポジトリでの配置はこの要素によって決まります。 「groupId + artifactId」がいわばこのプロジェクトの名前でもあり、住所でもあるわけです。 Webにおけるドメインやメールアドレスと同様に、世界で唯一のものです。

注3)http://maven.apache.org/pom.html

コマンドオプション

先ほど、「mvn archetype:create -DgroupId=jp.gihyo …」という長いコマンドを入力しました。 この「archetype:create」は「ゴール」と呼ばれ、Maven2プラグインが実行する処理名を表します (Antでのtargetに相当します)。 ここではプロジェクト作成プラグインである Maven Archetype Pluginのプロジェクト作成処理を実行するという意味になります。
「-DgroupId」などはオプションです。mvnコマンドを使う上でこのオプションはとても重要です。 mvn -hコマンドを実行するとオプションの一覧と説明が表示されます。 その中で、よく使うオプションを表1にまとめました。

表1 mvnコマンドのよく利用するオプション
オプション 説明
U スナップショットバージョンの依存ライブラリの更新を強制的にチェックする
D システムプロパティをセットする
(例:-DartifactId=webdb-webapp)
e maven実行時のエラーメッセージを出力する
o オフラインモードで実行する。インターネットに接続できないときや依存ライブラリの更新チェックを行いたくない場合に使用する
P 有効にするプロファイルを指定する


先ほど指定したDオプションの意味もこれでわかります。
-DgroupId=jp.gihyo -DartifactId=webdb-webapp
-DarchetypeArtifactId=maven-archetype-webapp

そもそも「-D」という表記はjavaコマンドのオプションと同じですので、 馴染みのあるものではないでしょうか? ここでは、groupIdに「jp.gihyo」、artifactIdに「webdb-webapp」、archetypeArtifactIdに 「maven-archetype-webapp」という3つのシステムプロパティをセットするという意味になっています。
システムプロパティarchetypeArtifactIdは、MavenArchetype Pluginが利用するオプションで、 ここでは「maven-archetype-webapp」とWebアプリケーション用ひな形の作成を指定しています。ライブラリ用ひな形を作成する場合は「maven-archetype-quickstart」としてください。

ビルドライフサイクル/フェーズ

先ほど、mvn packageコマンドでWARファイルが作成されることを体験しました。 この「package」とは何でしょうか?これはMaven 2の肝である「フェーズ」と呼ばれるものです。 フェーズはプロジェクトをビルドするための1つの処理をあらわします。 「コンパイルする」「ユニットテストを実行する」などです。 Maven 2でよく利用するフェーズを表2にまとめました。

表2 Maven 2でよく利用するフェーズ
フェーズ 説明
compile ソースコードをコンパイルする
test ユニットテストを実行する
package クラスファイルをJARやWARなどの配布形式にまとめる
install packageフェーズにて生成された成果物をローカルリポジトリに配置する
deploy 成果物をリモートリポジトリに配置する


たとえば「ユニットテストを実行する」処理(testフェーズ)を行う場合は、 事前にコンパイルなどが必要となるのですが、Maven 2ではこれらを自動的に実行してくれます。 これは「ビルドライフサイクル」と呼ばれるしくみのおかげです。
Maven 2には3つのビルドライフサイクルが定義されています(表3)。

表3 Maven 2のビルドライフサイクル
ビルドライフサイクル 説明
default デフォルト(validate→compile→test→package→integration→test→verifycinstall→deployフェーズが実行される)
clean クラスファイルなどMaven 2によって生成されたものを削除する(pre-clean→clean→post-cleanフェーズが実行される)
site プロジェクトサイトの生成と配置を行う(pre-site→site→post-site→site-deployフェーズが実行される)


ビルドライフサイクルはフェーズの実行順番を定義しているもので、たとえばdefaultビルドライフサイク ルでは、validate→compile→test→…→deployという順番が定義されており、 mvn testコマンドを実行すると、前フェーズであるvalidateとcompileがまず先に実行される しくみになっています(図3)。

図3 ビルドライフサイクルとフェーズ


なお、ビルドライフサイクルは、Maven 2のlibディレクトリ内のmaven-core-2.0.6-uber.jarに含まれているMETA-INF/plexus/components.xml ファイルにて定義されています。