Mavenとは何ぞや

少し前に書いた記事でMavenに~~ハメられた~~ハマってしまった。

【過去の記事】
[Mavenリポジトリのローカルキャッシュ](https://qiita.com/ASHITSUBO/items/0d30c1ddf476d2ec96b7)

そもそもMaven自体がどんなものかよくわからず使っていた上、問題への対処もその場しのぎ感。
「よくわからないけどなんとなく使えてる」というのは駆け出し技術者としても最高に格好が悪いため、これをきっかけにMavenについて調べてみようと思う。


#Mavenとは？
そもそもMavenとはなんなのか...

`Maven` は `Project Object Model (POM)` という考え方に基づき、プロジェクトのビルド、テスト、ドキュメンテーション、成果物の配備など、プロジェクトのライフサイクル全体を管理するものです。

プロジェクトに関する色々な情報を `POM` に集約し、`POM` の情報に基づきプロジェクト全体を管理します。

私が業務中で意識して触れていたのは、「プロジェクトの依存するライブラリの管理」程度でしたが、
本当に色々できるもののようです...


#Mavenの構成
以下の図は `Maven` のアーキテクチャを表したものです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/243642/164b9b8f-7816-3e51-54cd-a81b06d2315e.png)
(参考サイトより引用。サイトのURLは記事の最後に記載しています。)

ローカルリポジトリとリモートリポジトリ、よくわからんので噛み砕いてまとめました。

- それぞれのリポジトリにはプラグインやライブラリが置かれている。
- `Maven`は必要なプラグインやライブラリをリモートからダウンロードし、ローカルに保存する。
- ローカル環境にある全プロジェクトは、ローカルリポジトリに保存したライブラリを参照することができる。

また、`Maven`を使用すると、プロジェクトのライフサイクルに含まれるコンパイルやテストなどの各作業を、コマンド一つで行うことができます。

ここからは各作業について簡単にまとめていきます。

##コンパイル

```
mvn compile
```

プロジェクトをコンパイルするには上記コマンドを実行します。

`src/main/java/`配下ソースのコンパイルが行われます。
コンパイルにより作成されたクラスファイルは `target/classes` ディレクトリに出力されます。

##テスト

```
mvn test
```

ユニットテストを実行するには上記コマンドを実行します

デフォルトでは、以下のパターンにマッチするファイルがテストとして実行されます。

- `**/Test*.java`
- `**/*Test.java`
- `**/*TestCase.java`

また、以下のファイルはデフォルトで除外されます：

- `**/Abstract*Test.java`
- `**/Abstract*TestCase.java`
- `**/*$*`

##パッケージング

```
mvn package
```

JAR ファイルの作成 (パッケージング) を行うには上記コマンドを実行します。

成功すると `target` ディレクトリに `sample-1.0-SNAPSHOT.jar` が作成されていることが確認できると思います。

作成される JAR ファイルの名前は、`pom.xml` に記述されている `artifactId` と `version` から決定されます。

##インストール

```
mvn install
```

作成した JAR ファイルをローカルリポジトリにインストールするには、上記コマンドを実行します。

作成した JAR ファイルはローカルリポジトリにインストールすることで、ローカルにある他のプロジェクトから参照することができるようになります。

##公開

```
mvn deploy
```

作成した JAR ファイルをリモートリポジトリに配備するには、上記コマンドを実行します。



リモートリポジトリに配備するには、リモートリポジトリの情報を`pom.xml`に記述する必要があります。

リモートリポジトリの情報は、`project/distributionManagement`に入れ子として `repository`要素を追加します。
 `repository` の子要素には `id` (リポジトリの識別子), `name` (リポジトリの名前), `url` (リポジトリの場所を示す URL) などが指定可能です。

設定例：

```pom.xml
<project ...>
  ...
  <distributionManagement>
    <repository>
      <id>deploy-repository</id>
      <name>deployRepository</name>
      <url>file://${env.M2_HOME}/deployRepository</url>
    </repository>
  </distributionManagement>
  ...
</project>
```


この例では (リモートリポジトリという名前に反していますが)、リモートリポジトリの位置を、`Maven` のインストールされているディレクトリ以下の `deployRepository` として指定しています。

#pom.xml とは？
ここまで、`pom.xml`という単語が出てきたと思います。
`Maven`を使用する上で必要なことなのでこいつについてもまとめましょう。

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

project 要素以下の各要素が持つ意味は以下の通りです。

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

先ほど「`pom.xml` はプロジェクトに関する情報を持つ」と述べましたが、`pom.xml` の内容を見ると、ソースコードの場所やクラスファイルの出力先など、重要であろう情報が記述されていません。 これは、`pom.xml` にはデフォルトの設定というものがあり、ここで記述されていないものは、デフォルトの値が適用されているためです。

#まとめ
`Maven`について、全く理解できていませんでしたが、備忘録としてまとめる中で理解が深まったと思います。業務では`Eclipse`と連携させて使用しているため、今後はその辺りの詳細についても理解を深めていけたらと思います。

#参考サイト
Maven | TECHSCORE(テックスコア)
http://www.techscore.com/tech/Java/ApacheJakarta/Maven/1/#maven-1-1