はじめに
Jarファイルを作る際JDKを用いてjavaファイルを一つ一つコンパイルしてzipにまとめてjarに変えて...etc
なんてめんどくさいことはしませんよね?
pom.xmlを書いてしまえばMavenで実行してあげるだけであっという間にjarファイルを作ってくれます
それだけ?と思う方は一度他者と一緒にプロジェクトを進めることを考えてみてください
自分はクラスファイルをどこにおいてクラスパスをどこに通しどのライブラリをjarに含めるのか
どのリソースを一緒に含めてあげるのか...
すべて把握していて手動でできるといっても一緒にプロジェクトを進めている方が知るはずないですよね?
何はともあれpom書こう(脳死) Gradle書きたい方はこの記事はほとんど参考にならないんでブラウザバックしてどうぞ
pomの最低限の要素
<?xml version="1.0" encoding="UTF-8"?>
<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>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
</project>
この要素さえ最低限あれば一応pomとして働きます
groupId,artifactId,version以外はほとんどおまじないに近いですが一応説明します
<?xml version="1.0" encoding="UTF-8"?>
xmlなら必ず書く必要があるものです
バージョンは1.0が一般的です
文字コードはファイルを保存するときに指定したもの書いてください(だいたいUTF-8)
<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>
</project>
pomのルートノードです pomのバージョンやスキーマを指定するところですがほとんど定型文
おまじないの範疇でいいと思う
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
グループIdはプロジェクトがどこの団体or個人に属するものなのか区別するためのものです
わかりやすい例だと
Aさんの開発したプロジェクトがHogeという名前で
Bさんの開発したプロジェクトもHogeという名前だった場合
CさんがAさんとBさんの両方のプロジェクトに依存したHogeHogeプロジェクトなんかを作る際
AさんのHogeを使っているのかBさんのHogeを使っているのか区別できなくなります
人が区別できなくなる分にはまだましなのですがMavenが依存関係を構築する際も区別できなくなります
ここで活躍するのがグループIdです
だいたいは企業のドメインを逆にしたものです 個人ならプロジェクトを区別するためだけのものですから好きに付ければいい
Aさんならjp.a.project
Bさんならorg.group.b.project
あくまでプロジェクトを区別するためのものですからドメインを取得したりなんてことはしなくていいです
アーティファクトIdはプロジェクトの名前です お好きにどうぞ
バージョンは開発バージョンです beta-1.0とか 1.0-SNAPSHOTとか プロジェクトを区切る際に変更します
pomの主な要素
主に
properties
repositories
dependencies
build
を使います ほかにもいろいろありますが頻繁に書くのはこの4つです
properties・・・変数的なものです projectのデフォルト値やプラグインが参照する値もここで上書きできます
作ったプロパティーは${プロパティー名}で呼び出せます リソースの中でもフィルタリングを有効にすれば使えます
<properties>
<java.version>1.8</java.version>
<upload.password>1234</upload.password>
${upload.password}
</properties>
repositories・・・依存する外部ライブラリを取得する際のレポジトリのURLを記述します
MavenCentralレポジトリにあるライブラリはレポジトリの記述なしで依存関係を作れます
github上に作成されたMavenレポジトリなんかを参照する際に書きます
参照するレポジトリの数だけ書きます idはMavenが区別するためのものなので好きに書いていいです
<repositories>
<repository>
<id>test</id>
<url>https://~</url>
</repository>
<repository>
...
</repository>
</repositories>
dependencies・・・依存するライブラリを記述します
依存するライブラリのグループId アーティファクトId バージョンを書き込みます
スコープはcompile provided runtime test system の中から選びます
compileは常にクラスパスに含みます
providedはAPIなどの提供されるライブラリの場合使用します コンパイル時のみクラスパスに含まれます
runtimeは実行時のみ必要なライブラリの場合使用します 実行時にのみクラスパスに含まれます
testはテスト時のみ必要なライブラリ(JUnitとか)の場合使用します テストのコンパイルと実行時のみクラスパスに含まれます
systemは明示的にライブラリを指定する際に使用します あまり一般的ではないので説明は割愛
<dependencies>
<dependency>
<groupId>jp.a.project</groupId>
<artifactId>TestProject</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
...
</dependency>
</dependencies>
build・・・ビルドの手順を記述します
書く内容は使用するプラグインとそのゴールとフェーズのバインド
リソースの設定や成果物の生成場所 生成名なんかを記述します
プラグインとかバインドに関しては下で解説します
リソースはディレクトリとフィルタリングするかどうかを設定します
フィルタリングするとリソース内の${プロパティ名}が実行時の値に置き換えられます
<build>
<defaultGoal>clean package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
...
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
ビルドライフサイクル
Mavenにはビルドライフサイクルというものがあります
ライフサイクルは
クリーンライフサイクル ・・・ビルドのお掃除
デフォルトライフサイクル ・・・ビルドの作業
サイトライフルサイクル ・・・プロジェクトのサイト作成
の3つに分類されます
フェーズ
このライフサイクルはフェーズという作業の工程を細かく分類したものを持っています
クリーンライフサイクルなら
pre-clean : ビルドを削除する前に必要な処理
clean : 前回作成されたビルドの削除をする処理
post-clean : プロジェクトのクリーニングを完了するために必要な処理
デフォルトライフサイクルなら
validate :プロジェクトが正しいこと、および必要なすべての情報が利用可能であることを確認する処理
initialize :プロパティの設定やディレクトリの作成など、ビルド状態を初期化する処理
generate-sources :コンパイルに含めるソースコードを生成する処理
process-sources :ソースコードに対する処理 値のフィルタリングなど
generate-resources :パッケージに含めるリソースを生成する処理
process-resources :リソースをターゲットディレクトリーにコピーする処理
compile :プロジェクトのソースコードをコンパイルする処理
process-classes :生成されたクラスファイに対する処理
generate-test-sources :テストソースコードを生成する処理
process-test-sources :テストソースコードに対する処理 値のフィルタリングなど
generate-test-resources :テスト用のリソースを作成する処理
process-test-resources :リソースをテスト用ディレクトリーにコピーする処理
test-compile :テストソースコードをコンパイルする処理
process-test-classes :生成されたテストクラスファイルに対する処理
test :テストフレームワークを使用してテストを実行する処理 JUnitとか
prepare-package :パッケージを準備するために必要な処理
package :コンパイルされたコードをJARなどの配布可能な形式でパッケージ化する処理
pre-integration-test :統合テストを実行する前に必要な処理
integration-test :必要に応じて、パッケージを処理し、統合テストを実行できる環境に展開する処理
post-integration-test :統合テストの実行後に必要な処理
verify :検査を実行して、パッケージが有効であり、品質基準を満たしていることを確認する処理
install :ローカルリポジトリにパッケージをインストールする処理
deploy :パッケージをリモートリポジトリにコピーする処理
サイトライフサイクルなら
pre-site :サイトの生成前に必要な処理
site :プロジェクトのサイトドキュメントを生成する処理
post-site :サイト生成を完成させ、サイト展開の準備に必要な処理
site-deploy :生成されたサイトのドキュメントを指定されたWebサーバーにデプロイする処理
フェーズ実行
Mavenでビルドする際 mvn package などのコマンドを使用しますがそのpackageに該当するのがフェーズです
フェーズは実行されると同じビルドライフサイクル上の指定フェーズまでを上から順番に実行していきます
packageの場合 デフォルトサイクルに属するので validate~packageまでが順番に実行されます
ゴール
フェーズにはゴールというものがいくつか紐づけられています (デフォルトで)
このゴールは実際に行う処理です
フェーズが持つゴールをすべて実行して次のフェーズに進みます
packagingで選んだファイルの種類によってゴールの構成は変わるようですが
何も書かなければ自動でJarを生成する構成になります
ゴールを自分でフェーズに紐づけることで自分のしたい処理を加えることができます
このことをバインドするといいます
プラグイン
ビルドの際に行う処理(ゴール)はすべてプラグインが持つ機能を利用しています
このプラグインはJavaのプロジェクトで作られています なのでグループIdやアーティファクトId バージョンがあります
ゴールはクラスのメソッドを実行しているようなものだと思っとけばいいです
ゴールの実行時に引数のように値を渡して実行結果を変えたい場合
プラグインもしくはexecutionのconfigurationで変更することが可能です 指定しない場合プラグイン側のデフォルト値が適用されます
下の例だとmavenのcompilerプラグインとshadeプラグインを使用しています
jarの生成の場合デフォルトでcompileフェーズでcompileゴールを実行するのでcompilerプラグインは宣言するだけでいいです
shadeプラグインはデフォルトで実行されないのでバインドする必要があります
プラグインで検索すれば選択できるgoal名と設定できるconfigurationの詳細が書いてあるページがあるはずです
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
おまけ
Mavenが提供している公式のプラグインはmaven-○○○-pluginで統一されている
そのほかは○○○-maven-pluginで統一されている
最後に
Mavenを勉強していてプラグインに関する日本語の資料が少なくて苦労したのですこしでも誰かの知識になったらうれしい