Computer

Mavenの「よくわらない」を解消 ! ライフサイクル、フェーズ、バインドの概念

Mavenって分かるようでわからない。よくわからないまま日々使っているけど、いざカスタマイズしようとすると途端に訳がわからない。

そんな苦手意識を持っている人は意外と多いのではないでしょうか。

好き嫌いの問題はあれどMavenはJavaのビルドツールのデファクトスタンダードとなっています。僕の勤務先でもそうですが、多くのオープンソースプロジェクトがMavenを使っていて、すぐにMavenが消えてなくなることはないでしょう。

Dockerイメージと作ったり、Reactなどの非Javaのコードもビルドできるようになるには、正しい理解を持つ必要があります。このシリーズでは冒頭で挙げたような苦手意識を持つ方に向けてMavenの独特な概念を解説したいと思います。

packagingとは

まずpom.xmlには<packaging>という設定があります。packagingは「プロジェクトの成果物(artifact)の種類」を定義していて、主に使われるのは

  • pom
  • jar
  • war

あたりでしょうか。一つのpom.xmlで指定できるpackagingは一つのみです。

使用可能なパッケージングの一覧はこちらをご覧ください:https://maven.apache.org/pom.html

jarwarは見ての通り、それぞれjarファイルとwarファイルを生成します。jarはJavaモジュールやSpring Bootアプリケーションに使用し、warならばTomcatやWildFlyなどのコンテナにデプロイするWebアプリケーションとなります。

気になるのはpomというタイプですが、これは基本的には何も生成しません。

一般的には複数の子モジュールをまとめた親モジュール(aggregator POMともいいます)として使われますが、それ以外にもJavaScriptベースのアプリケーションをビルドしたりといった非Javaのビルドや、複数のjarやwarファイルをまとめて一つのzipにしたいなど、カスタムなビルドでもpomを使うことがあります。

ちなみにデフォルト値はjarなので、省略した場合はjarが使われます。

ビルドのライフサイクル

Mavenにはライフサイクルという概念があり、以下の3つのライフサイクルが存在します。

cleanライフサイクル

ビルド中に作られたファイルやディレクトリを削除するためのライフサイクル。

defaultライフサイクル

メインのビルド作業を行うためのライフサイクル

siteライフサイクル

あまり使う機会はないと思いますが、Mavenにはプロジェクトのウェブサイトを生成する機能が備わっていて、この機能を使うと、たとえばAPIドキュメントやプロジェクトの紹介、ビルド中に生成されたテストのレポートなどの情報をまとめたHTMLページを生成できます。siteライフサイクルはそのために使用されます。たとえば、このページや大半のMavenのサイトのページはMavenのサイト生成機能で作られているはずです。

ライフサイクルのイメージ

上記の三つのライフサイクルにはそれぞれに複数の「フェーズ」があって、順序もあらかじめ決められています

たとえばcleanライフサイクルならば、pre-clean、clean、post-cleanという順序でフェーズがバインドされています。

blank

* 詳細なフェーズの一覧はこちらをご覧ください。

たとえば

mvn clean

というコマンドを打つと、「cleanライフサイクルのcleanフェーズまでを実行せよ」、つまり「pre-cleanフェーズとcleanフェーズを実行せよ」という意味になります。

また

mvn clean install

とあれば「cleanライフサイクルのcleanフェーズまでを実行したのち、defaultライフサイクルのinstallまでの全フェーズを実行せよ」という意味になります。

実際の作業はプラグインの役目

Mavenにはライフサイクルがあり、各ライフサイクルには複数のフェーズが順番に並んでいるわけですが、最終的なビルドのタスクを実行するのはプラグインの仕事です。

各プラグインには「ゴール」というものが存在します。ゴールというのはメソッドのようなもので、「コンパイルをしなさい」とか「ディレクトリをクリーンアップしなさい」といった具体的な指令になります。

でも先ほどのコマンドをもう一度見てみてください。

mvn clean

どこにも「このプラグインのあのゴールを呼び出してクリーンアップしろ」なんて書いてありません。でも実際にはmaven-clean-pluginというプラグインのcleanというゴールが実行されます。

これはMaven内部に「cleanというフェーズに来たら、cleanプラグインのcleanゴールを実行しろ」というデフォルトの定義があるためです。

これをMavenのドキュメント内では「フェーズにゴールがバインドされる」と表現していて、各フェーズにはデフォルトでバインドされるプラグインのゴールがあらかじめ決まっています。詳細はこちらをご覧ください。

https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Built-in_Lifecycle_Bindings

そして、どのフェーズでどのプラグインが実行されるのかをよくみてください。上述したpackagingのタイプによってバインドされるプラグインが若干異なることにも注意してください。

ここまでを理解すると、installというフェーズを呼び出すとなぜコンパイルやテストが実行されるのかがご理解いただけると思います。

Mavenの誤解しやすい用語

Mavenにおいては誤解しやすい用語がいくつかあるので、それを解説します。

インストール

Mavenにはレポジトリという概念があります。レポジトリは生成されたビルドの成果物(artifact)を保存するための場所であり、GitやSVNなどのソースコードレポジトリとは別のものです。

レポジトリにはローカルとリモートがあり、ローカルレポジトリはリモートレポジトリのキャッシュとして使われたり、ローカルで作られたビルド成果物を登録して、別のモジュールからも利用可能にする役割があります。

インストールとは、でき上がった成果物をローカルレポジトリに登録することをいいます。

デプロイ

一方、リモートレポジトリに成果物を登録することをデプロイと呼んでいます。

リモートレポジトリに発行されると、別のコンピュータもこのアーティファクトをダウンロードして利用することができます。Tomcatなどのサーバーに生成したアプリケーションをデプロイするという意味ではないので誤解しないようにしましょう。

まとめ

今回は、Mavenの核となるライフサイクルとフェーズ、そして各フェーズにバインドされるプラグインゴールの仕組みについて解説しました。

次回は任意のフェーズに任意のプラグインをバインドする方法を取り上げます。

 

-Computer

Copyright© dawaan , 2020 All Rights Reserved.