Maven基礎
2013/9/30
株式会社アークシステム
瀧口 季男
Mavenって?
Apache Maven is a software project
management and comprehension tool.
Based on the concept of a project
object model (POM), Maven can
manage a project's build, reporting and
documentation from a central piece of
information.
http://maven.apache.org

上に書いてある通り、ソフトウェアプロジェ
クトの管理&支援ツールです。
Javaでコンパイル
~どうやるんだっけ?~
javacって、ありましたよね?
コンパイル?
javac -cp lib/foo.jar;lib/baa.jar;lib/poo.jar
-source 1.5 -target 1.5 -d classes
src/com/example/foo/*.java
src/com/example/baa/*.java

JAR?
jar cvf hoge.jar -C classes/ .

実行?
java –cp
classes;lib/foo.jar;lib/baa.jar;lib/poo.jar
com.example.foo.Main arg…

私には無理です。本当にありがとうございました。
Ant
~それは革命~
さよならシェルスクリプト
build.xmlを書いておけば、ant compile
でコンパイルできる!
<project name="hoge" default="jar" basedir=".">
<target name="compile">
<javac destdir="bin" encoding="UTF-8">
<src path="src" />
<classpath>
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</classpath>
</javac>
</target>
<target name="jar" depends="compile">
<jar jarfile="dist/hoge.jar" basedir="bin"></jar>
</target>
</project>
Antがあってよかったなって
Write once, build anywhere!
ビルドに必要なソース、依存JAR、
build.xmlとAntが一式あれば、Windowsで
もLinuxでもビルドできる!
パーキンソンの法則
仕事は、その遂行のために利
用できる時間をすべて埋める
ように拡大する
Antあるある
オレオレbuild.xml
「私のプロジェクトでは、モジュール名をソー
スディレクトリ名とする キリッ」

依存JARが増えると・・・
いちいちサイト巡ってダウンロードするのめん
どくせ (‘A`)
SCMにJARを全部コミットしたらサーバーのHDD
が・・・

あれ、デジャビュ?
このAnt task、夢の中で書いた、ような・・・
いちいちbuild.xml書くのめんどくせ (‘A`)
ヒックの法則
意思決定にかかる時間は、可
能な選択肢の数に依存する
じゃ、決めちゃおうぜ
プロジェクトのディレクトリ構成
決めても従わない奴ばかりだとしても、もし最初
からディレクトリ構成を作ってくれるとした
ら?

依存jarの解決
あちこち探してダウンロードするんじゃなくて、
1箇所に集まってたら?さらに、自動でダウン
ロードしてくれるとしたら?

ビルドの流れ
コンパイルして、テストして、ZIPで固めて・・
__ __
| ¥/ |__ _Apache__ ___
| |¥/| / _` ¥ V / -_) ' ¥ ~ intelligent projects ~
|_| |_¥__,_|¥_/¥___|_||_| v. 1.0.2

~ビルドツールのその先へ~
ディレクトリ構成決めました
これで行くから。
[basedir]
├ pom.xml
├ src
│ ├ main
│ │
├ java
│ │
└ resources
│ └ test
│
├ java
│
└ resources
└ target
├ classes
└ test-classes

src/main/webapp、src/siteなどもある
maven 1.0 の頃は、mainとtestが分かれてなかっ
た。時代の流れを感じるところ。
http://maven.apache.org/guides/introduction/introductio
n-to-the-standard-directory-layout.html
JARのリポジトリ作りました
セントラルリポジトリにたくさんのJARを集めて公
開するよ
個々のJARを識別する仕組みも考えたよ
groupId、artifactId、versionで特定するよ
依存するJARを設定ファイルに書いて明確化できるよ

ビルド時に自動で依存を解決するよ
リポジトリからJARをダウンロードするよ
ダウンロードしたJARがSCM管理下に入らないように、
こっそり別の場所に保存しておくよ

http://maven.apache.org/guides/introduction/introductio
n-to-repositories.html
ビルドの流れを決めました
Clean

Site

validate

pre-clean

pre-site

compile
Build Lifecycle

Default

clean

site

test

post-clean

post-site

package
integration
-test

verify
install
deploy

site-deploy

Mavenには3種類のライフサイク
ルがある
Defaultライフサイクルは、実際
もっと細かいフェーズに分かれ
ている(全部で23個!)

http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference
ここまでのまとめ
javacからAnt
ビルドの定型化、環境非依存化
開発が大規模化するにつれ、冗長なところ
が多くなった

AntからMaven
ビルドの普遍化、環境の統一化
Mavenがうごくしくみ
~Goal & Lifecycle~
Maven本体とゴール
Maven本体の機能
POM(後述)の解析
ライフサイクルの各フェーズに結びつい
たゴールの実行

ゴール
ビルドの個々のタスク。コンパイル、JAR
作成、ファイルのコピーなどなど。
ゴールは全てプラグインが提供する
Goalの実行
個々のプラグイン名:ゴール名で、1
個のゴールを実行する
compiler
:compile

> mvn

compile

Maven

dependency

resolve
copy
list

compiler

compile
testCompile

surefire

test

jar

jar
test-jar

pluginたち
Phaseの実行
ライフサイクル中の指定したPhaseま
で、各Phaseに紐付いたゴールを実行
する
各Phaseに結びつ
resolve
いたGoalを実行

> mvn
test

dependency

Maven
validate
compile
test

validate

copy
list

compiler

compile
testCompile

surefire

test

compile
test
package
・
・
・

jar

jar
test-jar
実行の仕方
mvn [options] [<goal(s)>] [<phase(s)>]

Goal
Mavenに実行させたいタスクの指定
[プラグイン名]:[ゴール名]で指定する
mvn compiler:compile
mvn jar:jar

Phase
ビルドライフサイクルをどのフェーズま
で実行するか、という指定
各フェーズには、複数のゴールが結びつ
いている
Mavenの設定
~POM~
POM “Project Object Model”
プロジェクト情報をXMLで記述する
<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>hoge-project</artifactId>
<version>1.0.0</version>
<!-- その他色々な設定 -->
</project>

いくつか紹介しますが、詳しくはWeb
で!
http://maven.apache.org/pom.xml
dependencies
プロジェクト依存ライブラリの設定
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>hoge</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>…</dependency>
</dependencies>

groupId, artifactId, version
JARを一意に特定するキー
scope
いつ必要なのかを指定する
compile (デフォルト)
provided
runtime
test
system

ローカルに無ければ、自動でリポジトリからダ
ウンロードされる
Mavenのセントラルリポジトリ以外のリポジトリ
は repositories に設定する必要あり
build
ビルドに関する設定(プラグイン等)
<build>
<defaultGoal>validate</defaultGoal>
<resources>
<resource>…</resource>
</resources>
<plugins>
<plugin>…</plugin>
</plugins>
</build>

defaultGoal
goal/phase指定が無い場合に実行さ
れるgoal/phaseを指定する

resources
成果物に含める、含めないリソース
(*.properties, *.xml等) を設定する

plugins
ビルドに使用するプラグイン設定
プラグインの追加
phaseにgoalを結びつけ
プラグインの引数設定

ソースディレクトリ、ビルドしたclass
ファイルの出力先を変更することもでき
る
でも、基本的にやらない。
build - plugin
ビルドにプラグインを追加
<plugin>
<groupId />
<artifactId />
<version />
<configuration>…</configuration>
<executions>
<execution>
<id>taskname</id>
<phase>compile</phase>
<goals>
<goal>doTask</goal>
</goals>
<configuration>…</configuration>
</execution>
</executions>
</plugin>

groupId, artifactId, version
プラグインを特定するキー

configuration
プラグインの引数設定

execution
phaseにgoalを結びつける
phase
紐付け先のフェーズ

goal
フェーズで実行するプラグインのgoal
parent (Super POM)
親POMの設定
<parent>
<groupId>com.example</groupId>
<artifactId>hoge</artifactId>
<version>1.0.0</version>
<relativePath>…</relativePath>
</parent>

依存ライブラリのバージョン、ビルド時
のプラグイン設定などを書いた親POMを
引き継ぐことができる
build - pluginManagement
プラグインの一括管理
<pluginManagement>
<plugins>
<plugin>…</plugin>
</plugins>
</pluginManagement>

親POMに書いておけば、子モジュールに
引き継がれる
マルチモジュール構成で活躍
dependencyManagement
依存ライブラリの構成管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId />
<artifactId />
<version />
<scope />
</dependency>
<dependency>…</dependency>
</dependencies>
</dependencyManagement>

dependencyと同じ
JARを一意に特定するキー

アーティファクトの属性 (version, scope,
exclutions) を設定でき、dependenciesで個別に指
定する必要が無くなる
profile
環境に応じて設定を切り替えるしくみ
<profiles>
<profile>
<id>production</id>
<activation>…</activation>
<build>…</build>
<dependencies>…</dependencies>
</profile>
<profile>…</profile>
</profiles>

activation
プロファイルを有効化する条件を設定する

build
プロファイルごとのビルド設定

dependencies
プロファイルごとの依存関係

例えば
3つのprofile (本番, 保守, 開発) を用意し、DB接続設定
ファイルを切り替える
JDKのバージョンに応じたJARを生成するため、コンパ
イル対象とするソースファイルを差し替える
Mavenを使う人が知っておく
べき97のこと
M2_HOME
Mavenインストールディレクトリを指
す環境変数
Mavenの実行には、%M2_HOME%の設
定と、%M2_HOME%/bin をPATHに通
す必要がある
ローカルレポジトリ
Mavenが自動でダウンロードしたJAR
(依存関係、プラグイン)が格納され
るディレクトリのこと
[ユーザーのホームディレクトリ]/.m2
リポジトリのミラーを設定する
セントラルリポジトリにあるはずなの
にJARがダウンロードできない!
セントラルリポジトリが落ちてた
よ・・・

そんなときは
ホームディレクトリの.m2/settings.xmlで
ミラーを設定する <settings>
<mirrors>
<mirror>
<id>UK</id>
<name>UK Central</name>
<url>http://uk.maven.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
リポジトリを追加する
セントラルリポジトリに無いライブラ
リ(Seasar、JBoss、etc…)を利用す
る場合は、リポジトリの設定をPOMに
追加する
<repositories>
<repository>
<id>maven.seasar.org</id>
<name>The Seasar Foundation Maven2 Repository</name>
<url>http://maven.seasar.org/maven2</url>
</repository>
</repositories>
プラグインリポジトリを追加する
ビルドで使用するプラグインがセント
ラルリポジトリに存在しない場合は、
プラグインリポジトリの設定をPOMに
追加する
<pluginRepositories>
<pluginRepository>
<id>maven.seasar.org</id>
<name>The Seasar Foundation Maven2 Repository</name>
<url>http://maven.seasar.org/maven2</url>
</pluginRepository>
</pluginRepositories>

Maven 3 はリポジトリの解釈が厳密化され、
repositoriesからプラグインを解決しないよう
になった
良く使うフェーズ
clean

targetディレクトリを削除する。ソースから一部
のファイルを削除した等の理由でフルビルドした
いときに使う。

package

JAR等、最終成果物を生成する。POMを書く人は、
このフェーズでリリース物が出来るように設定す
るつもりで。

install
生成したJARをローカルリポジトリにコピーする。
当該プロジェクトを参照する他のプロジェクトか
ら、JARを利用できるようになる。
IDE と統合する
Eclipse
m2e
EclipseのMaven統合プラグイン
Indigo (3.7) から統合済み、Kepler (4.3) からはm2e-wtpも統合

Mavenに投資しているSonatypeが開発元

maven-eclipse-plugin
POMからEclipseの.projectと.classpathを生成する、
MavenのEclipse対応プラグイン
dependencyのscopeを解釈できないのでお勧めしない

NetBeans
最初からMaven統合済み

IntelliJ
たぶんイケる(誰か買ってください
テストをスキップする
もちろんそんなこと有り得ない訳ですが。
ソースをチェックアウトしてビルドしてみたら、
テストが通らない
テストが通らないのでJARができず、関連プロ
ジェクトが全部ビルドできない
テストが通ってなくてもいいから、とりあえず
JARが欲しい

そんなときは
mvn install -DskipTests

テストクラスのコンパイル自体できない?
mvn install -Dmaven.test.skip
残りの9xのこと
Maven2のTipsを集めるWiki
http://wiki.fdiary.net/maven2/
誰でも編集できるので、何かあったら書
きましょう

Maven基礎