Gradleを使ったJavaプロジェクトのビルド

# Javaプラグインとは

GradleでJavaプロジェクトをビルドするには、Javaプラグインが必要となる。
プラグインを適用するには、build.gradleに以下を記述する。

```gradle:build.gradle
apply plugin: 'java'
```

Javaプラグインは「タスク」「規約」「プロパティ」「ソースセット」の4つの要素が
パッケージングされたコンポーネントである。
それぞれの要素について学習することで、Javaプラグインを使ったビルドの動きを理解する。

# ソースセット

ソースセットとは、**同時にコンパイルを行うべき対象**をグループ化した概念である。
Javaプラグインでは、デフォルトで

- main：プロダクションコードおよび本番用のリソースをまとめたソースセット
- test：テストコードおよびテスト用のリソースをまとめたソースセット

上記2つのソースセットを提供している。

ソースコードは次のような特徴を持つ。

- ビルドスクリプトで自由に追加できる
- 一意な名前を持つ
- コンパイル対象となる「Javaソース」と「リソース」のセットを指定できる
- コンパイル結果の生成物(クラスファイルなど)を出力するパスを指定できる
- コンパイル時、および実行時のクラスパスを指定できる
- タスク及びプロパティをソースセットごとに設定できる

# タスク

Gradleでは、プラグインを追加すると、同時にビルドに必要な作業がタスクとして追加される。
Javaプラグインも、以下のタスクが追加される。

|タスク|説明|
|:--|:--|
|compileJava|プロダクションコードのコンパイルを行う。対象はソースセットmainのjava.srcDirsプロパティで指定したディレクトリに格納された、拡張子が.javaのファイル。|
|processResources|プロダクションコードのリソースをクラスパスにコピーする。対象はソースセットmainのresources.srcDirsプロパティで指定したディレクトリに格納された、拡張子が.java以外のファイル。|
|classes|compileJavaとprocessResourcesタスクを実行する。|
|compileTestJava|ソースセットtestに対してcompileJavaタスクと同じ動きをする。|
|processTestResources|ソースセットtestに対してprocessResourcesタスクと同じ動きをする。|
|testClasses|compileTestJavaとprocessTestResourcesタスクを実行する。|
|jar|JARファイルを生成する。デフォルトのアーカイブ対象はmainソースセットのoutputプロパティ。(compileJavaとprocessResourcesタスクの出力)|
|javadoc|mainソースセットのJavadocを出力する。|
|test|testソースセットに含まれるテストを実行する。デフォルトでのテスト対象はtestClassesタスクの出力から自動で抽出される。|
|uploadArchives|アーティファクト(ビルドの成果物)のアーカイブをリポジトリなどにアップロードする。|
|clean|ビルド出力を削除する。デフォルトではbuildディレクトリが削除される。|
|clean \<TaskName\>|指定したタスク\<TaskName\>の出力のみを削除する。|
|assemble|テストを実行せず、プロジェクト内容に応じて適切なアーティファクトを生成する。Javaプラグインのデフォルトではjarタスクと等価である。|
|check|プロジェクトの検証を行う。Javaプラグインのデフォルトではtestタスクと等価である。|
|build|プロジェクトのビルドを行う。checkとassembleタスクを実行する。|
|buildNeeded|ビルド対象のプロジェクトだけでなく、依存関係を設定したプロジェクトも含め、ビルドを行う。|
|buildDependents|ビルド対象プロジェクトに依存しているプロジェクトも含め、ビルドを行う。|

## ソースセットの追加とタスクの自動追加
Javaプラグインでは、ソースセットを追加すると
ソースセットごとに次のタスクが自動的に追加される。

- compile\<SourceSet\>Java
- process\<SourceSet\>Resources
- \<SourceSet\>Classes

# 規約

規約とは、「JavaプロジェクトではJavaファイルをsrc/main/javaディレクトリ配下に配置する」
といったような約束事である。Javaプラグインには以下の規約がある。

- プロダクションコードのソースファイル  
→ src/main/javaディレクトリ配下に配置する
- プロダクションコードのリソース  
→ src/main/resourcesディレクトリ配下に配置する
- テストコードのソースファイル  
→ src/test/javaディレクトリ配下に配置する
- テストコードのリソース  
→ src/test/resourcesディレクトリ配下に配置する

# プロパティ

プロパティはタスクの入出力対象や、規約のディレクトリなどを制御するために設定する。

## Javaプラグインのプロパティ(共通)
Projectオブジェクトが提供するプロパティ。

|プロパティ|説明|デフォルト|
|:--|:--|:--|
|testResultDir|テスト結果のXMLファイル出力先|build/test-results|
|testReportDir|テストレポート(HTML)出力先|build/reports/tests|
|libsDir|ライブラリ(JARファイル)出力先|build/libs|
|distDir|ディストリビューション(JARファイル以外のアーカイブ)出力先|build/distributions|
|docsDir|Javadocなどのドキュメント出力先|build/docs|
|sourceSets|プロジェクトのソースセット|main、testソースセットのコンテナ|
|sourceCompatibility|Javaソースコンパイル時のJavaバージョン|ビルドスクリプト実行環境のJVMのバージョン|
|targetCompatibility|コンパイル時のクラス生成のターゲットに指定するJavaバージョン|sourceCompatibilityの値|
|archivesBaseName|JARなどのアーカイブファイルのベースネーム|project.nameプロパティの値(デフォルトはプロジェクトのルートディレクトリ名)|
|manifest|全てのJARファイルに含めるマニュフェスト|なし|

```gradle:ビルドスクリプトにおけるプロパティへのアクセス
println project.docsDir
println docsDir
```

## Javaプラグインのプロパティ(ソースセットごとに提供)
ProjectオブジェクトのsourceSetsプロパティが提供するプロパティ。

|プロパティ|説明|デフォルト|
|:--|:--|:--|
|name|ソースセット名。プロジェクト内で一意の値であること|なし|
|output|ソースセットの出力|output.classDir、output.resourceDirプロパティの値|
|output.classDir|ソースセットのクラスファイル出力先|build/classes/\<sourceSet\>|
|output.resourcesDir|ソースセットのリソース出力先|build/resources/\<sourceSet\>|
|compileClasspath|ソースセットのコンパイル時クラスパス|コンフィグレーションcompile\<SourceSet\>の設定値|
|runtimeClasspath|ソースセットの実行時クラスパス|outputプロパティ、コンフィグレーションruntime\<sourceSet\>の設定値|
|java|ソースセットのJavaソース全て|src/\<sourceSet\>/java配下の拡張子が.javaのファイル|
|java.srcDirs|ソースセットのJavaソースを含むディレクトリ|src/\<sourceSet\>/java|
|resources|ソースセットのリソース全て|src/\<sourceSet\>/resources配下の拡張子が.javaでないファイル|
|resources.srcDirs|ソースセットのリソースを含むディレクトリ|src/\<sourceSet\>/resources|
|allJava|ソースセットの全てのJavaソース|javaプロパティの設定値(プラグイン適用で変更の可能性あり)|
|allSource|ソースセットの全てのJavaソースとリソース|java、resourcesプロパティの設定値(プラグイン適用で変更の可能性あり)|

```gradle:ビルドスクリプトにおけるプロパティへのアクセス
println project.sourceSets.test.compileClasspath
println sourceSets.test.compileClasspath
println sourceSets['test'].compileClasspath
```

# 参照

この記事は以下の書籍を参考に執筆しています。

参考書籍：[Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築](https://www.shoeisha.co.jp/book/detail/9784798136431)