新卒技術者がMavenについて勉強してみた

こんにちは。syamaです。
以前に仕事でMavenを使う機会があったのですが、よく理解しないままに何となく利用出来てしまったので、この場を使って何のためのサービスなのかをまとめてみることにしました。

## そもそもMavenって何なの？
__Apache Mavenは、ソフトウェアプロジェクトの管理・理解ツールである。プロジェクト・オブジェクト・モデル（POM）の概念に基づき、Mavenはプロジェクトのビルド、レポート、ドキュメンテーションを一元的に管理することが出来る。__（[公式サイト](https://maven.apache.org/)より引用・訳）

……なるほどね（分かってない）。
ようは、Javaベースのプロジェクトの構築や管理をすることが出来るツールらしい。

POMと言えば、私がMavenを利用した際にも確かに`pom.xml`というファイルを指定してプロジェクトのビルドを行っていました。

## このpom.xmlって何なんだ？？
pom.xmlは、プロジェクトに関する情報を持つ重要なファイル。プロジェクトのビルドに関する情報や、依存するライブラリの情報、プラグインの設定などが含まれます。

以下は、プロジェクト作成直後のpom.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/maven-v4_0_0.xsd">
     <groupId>com.example</groupId>
     <artifactId>sample</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>Maven Quick Start Archetype</name>
     <url>http://maven.apache.org</url>
     <dependencies>
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
       </dependency>
     </dependencies>
    </project>

project要素以下の各要素が持つ意味は以下の通りです。
|要素名|意味|
|:--|:--|
|modelVersion|POM のバージョン。 特に変更する必要はありません。|
|groupId|プロジェクトを一意に識別する名前。 プロジェクトのルートパッケージ名を指定するのが一般的です。|
|artifactId|プロジェクトの成果物の名前。 作成する JAR や WAR, EAR ファイルなどの名前に使用されます。|
|packaging|作成する成果物のパッケージング・タイプ。 jar (デフォルト), war, ear などがあります。|
|version|プロジェクトのバージョン。|
|name|プロジェクトの表示名。 ドキュメントを作成するときなどに使用されます。|
|url|プロジェクトのサイトの URL。 ドキュメントを作成するときなどに使用されます。|
|dependencies|プロジェクトが依存するライブラリの情報。|

これらの情報はpom.xmlに記述しなくても動作します。記述しなかった場合、デフォルトの値が適用されるようになっています。

## Mavenのアーキテクチャ
以下はMavenのアーキテクチャを表した図です。（[画像はTECHSCOREより引用](https://www.techscore.com/tech/Java/ApacheJakarta/Maven/2/#maven-2-1)）
![Mavens-Architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622599/d5f57ee0-0d00-8c44-a214-e8bd68011e7d.png)
リモートリポジトリとローカルリポジトリにはプラグインやライブラリが配置され、Mavenでは必要なプラグインやライブラリをリモートリポジトリからダウンロードし、それをローカルリポジトリに保存します。
このリモートリポジトリは独自のものを用意することも出来るので、例えば社用のリポジトリを用意して作成したプロジェクトをそこに配置する、といった使い方ができます。
これら一連の流れを行うためのコマンドについてこれ以降で説明していきます。


## 実際の使い方
### Mavenのインストール
下記サイトから、任意のバージョンのMavenをダウンロードします。
[http://maven.apache.org/](http://maven.apache.org/)

次に、環境変数の設定を行います。設定する変数は以下の2つ。

    $ export JAVA_HOME={JDKがインストールされているディレクトリのパス}
    $ export PATH={JDKがインストールされているディレクトリのパス}/bin:$PATH

以下の作業が終了したら、次のコマンドを入力します。

    mvn --version
これでバージョン情報が表示されれば、インストールは完了です。

### Mavenのコマンド
Mavenを仕様すると、プロジェクトのライフサイクルに含まれるコンパイルやテストなどの各作業をコマンド一つで行うことが出来ます。
#### プロジェクトの作成
Mavenにはプロジェクトのスケルトン（雛形）を作成する機能があるので、それを利用してプロジェクトを作成します。利用するコマンドは以下。

    　mvn archetype:create -DgroupId={プロジェクトのルートパッケージ名} -DartifactId={プロジェクトの名前}
これによって、カレントディレクトリにDartifactIdで指定した名前のプロジェクトが作成されます。この中には、プロジェクトに関する情報を持つpom.xmlも含まれています。

#### コンパイル
プロジェクトのコンパイルには以下のコマンドを利用します。

    mvn compile
コンパイルにより作成されたクラスファイルは`target/classes`ディレクトリに出力されます。

#### ユニットテスト
ユニットテストの実行には以下のコマンドを利用します。

    mvn test
デフォルトでは、以下のパターンにマッチするファイルがテストとして実行されます。
- **/Test*.java
- **/*Test.java
- **/*TestCase.java

#### ドキュメンテーション
以下のコマンドを利用してJavadocを作成することができます。

    mvn javadoc:javadoc
実行すると、`target/javadoc`ディレクトリにJavadocが作成されます。

また、以下のコマンドを利用してプロジェクトのサイトを作成することができます。

    mvn site
こうして作成されるサイトにはプロジェクトの依存するライブラリの情報などが含められますが、現状では文字列処理が正しく行われないらしく、日本語などのマルチバイト文字が文字化けしてしまう問題があります。

#### JARファイルの作成
以下のコマンドを実行してJARファイルのパッケージングを行います。

    mvn package
成功するとtargetディレクトリにJARファイルが作成されます。

#### ローカルリポジトリへのインストール
以下のコマンドを利用して、作成したJARファイルをローカルリポジトリにインストールします。

    mvn install
こうして作成したJARファイルはローカルにある他のプロジェクトから参照することができます。

#### リモートリポジトリへの配備
以下のコマンドを実行することで、作成したJARファイルをリモートリポジトリに配備することができます。

    mvn deploy
これを利用するには、事前にリモートリポジトリの情報をpom.xmlに記述しておく必要があります。リモートリポジトリの情報は、pom.xmlのproject/distributionManagement要素の入れ子としてrepository要素を追加して記述します。repositoryの子要素にはid(リポジトリの識別子)、name(リポジトリの名前)、url(リポジトリの場所を示すURL)などを指定できます。

#### プロジェクトのクリーン
以下のコマンドを実行することで、プロジェクトをクリーン（生成したファイルを削除）することができます。

    mvn clean
このコマンドを実行すると、targetディレクトリが削除されます。

## まとめ
さて、Mavenがどのようなサービスなのか、どのようにして利用するのかを軽く調べることができました。結論としてはjavaベースのプロジェクトの構築や管理の一連のプロセスをMaven一つ、コマンド一つで行うことが出来る包括的な管理ツールといった感じでしょうか。
javaを用いた開発を行う際にはかなり便利だと感じたので、業務以外で個人的にも動かして試してみたいですね。
ここまで読んでいただきありがとうございました。これからも気になることがあったら色々調べていこうと思います。

## 参考
Apache Maven Project - Maven
[https://maven.apache.org/what-is-maven.html](https://maven.apache.org/what-is-maven.html)

Maven - TECHSCORE
[https://www.techscore.com/tech/Java/ApacheJakarta/Maven/](https://www.techscore.com/tech/Java/ApacheJakarta/Maven/)