
はじめに
組み込みのタスク gradle init を使うことで新しい Gradle プロジェクトを簡単に作成できます。
Gradle 6.7 では、新しい推奨構成でプロジェクトが作成されるようになりました。
旧来のプロジェクト構成
旧来は gradle init により application プロジェクトを作成した場合は以下のようなプロジェクト構成となっていました。
.
├── build.gradle
├── settings.gradle
└── src
└── main
└── java
└── App.java
settings.gradle は以下のようになります。
rootProject.name = 'example'
build.gradle は以下のようになります。
plugins {
id 'java'
id 'application'
}
repositories {
jcenter()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
implementation 'com.google.guava:guava:29.0-jre'
}
application {
mainClassName = 'example.App'
}
test {
useJUnitPlatform()
}
新しいプロジェクト構成
Gradle 6.7 で JVM言語用の application プロジェクトを作成すると以下のようになります。
$ gradle init Select type of project to generate: 1: basic 2: application 3: library 4: Gradle plugin Enter selection (default: basic) [1..4] 2 Select implementation language: 1: C++ 2: Groovy 3: Java 4: Kotlin 5: Scala 6: Swift Enter selection (default: Java) [1..6] 3 Split functionality across multiple subprojects?: 1: no - only one application project 2: yes - application and library projects Enter selection (default: no - only one application project) [1..2] 1 ...
Split functionality across multiple subprojects?: という選択肢が追加されています。
1 を選択した場合は以下のようなプロジェクトが作成されます。
.
├── settings.gradle
└── app
├── build.gradle
└── src
└── main
└── java
└── App.java
ルートにあった build.gradle は app の中に配備されるようになりました。
settings.gradle は以下のようになり、app をインクルードしています。
rootProject.name = 'example' include('app')
build.gradle は以下のようになります。
plugins {
id 'application'
}
repositories {
jcenter()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
implementation 'com.google.guava:guava:29.0-jre'
}
application {
mainClass = 'example.App'
}
tasks.named('test') {
useJUnitPlatform()
}
もし、モジュールlib を追加する場合は以下のように追加し、
. ├── app │ ... │ └── build.gradle ├── lib │ ... │ └── build.gradle └── settings.gradle
settings.gradle でインクルードすればOKです。
rootProject.name = 'example' include 'app' include 'lib'
application and library projects
先程の選択肢で application and library projects を選択します。
... Split functionality across multiple subprojects?: 1: no - only one application project 2: yes - application and library projects Enter selection (default: no - only one application project) [1..2] 1
プロジェクト構成は以下のようになります。
.
├── settings.gradle
├── buildSrc
│ ├── build.gradle
│ └── src
│ └── main
│ └── groovy
│ ├── example.java-application-conventions.gradle
│ ├── example.java-common-conventions.gradle
│ └── example.java-library-conventions.gradle
├── app
│ ├── build.gradle
│ └── src
│ └── main
│ └── java
│ └── example
│ └── app
│ ├── App.java
│ └── MessageUtils.java
├── list
│ ├── build.gradle
│ └── src
│ └── main
│ └── java
│ └── example
│ └── list
│ └── LinkedList.java
└── utilities
├── build.gradle
└── src
└── main
└── java
└── example
└── utilities
settings.gradle では app, list, utilities をインクルードする構成になっています。
rootProject.name = 'example' include('app', 'list', 'utilities')
app/build.gradle は以下のようになります。
plugins {
id 'example.java-application-conventions'
}
dependencies {
implementation project(':utilities')
}
application {
mainClass = 'example.app.App'
}
utilities/build.gradle は以下のようになります。
plugins {
id 'example.java-library-conventions'
}
dependencies {
api project(':list')
}
list/build.gradle は以下のようになります。
plugins {
id 'example.java-library-conventions'
}
dependencies にて、app -(implementation)-> utilities -(api)-> list のように依存が定義されています。
そしてそれぞれの plugins に example.java-application-conventions のような convention が設定されています。
この convention プラグインは buildSrc の中に配備された以下のファイルで定義されたものです。
│ └── src │ └── main │ └── groovy │ ├── example.java-application-conventions.gradle │ ├── example.java-common-conventions.gradle │ └── example.java-library-conventions.gradle
buildSrc/build.gradle は以下のような定義になっています。
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
}
'groovy-gradle-plugin' によりbuildSrc 内の Groovy で書かれた convention プラグインが、メインビルドのプラグインとして利用できるようになります。
では convention プラグインの中身はどのようになっているでしょう。
app/build.gradle にプラグインとして定義されている example.java-application-conventions.gradle は以下のようになっています。
plugins {
id 'example.java-common-conventions'
id 'application'
}
application プラグインに加え、example.java-common-conventions プラグインを利用しています。
utilities/build.gradle と utilities/build.gradle から利用されている example.java-library-conventions.gradle は以下のようになっています。
plugins {
id 'example.java-common-conventions'
id 'java-library'
}
java-library プラグインに加え、こちらも example.java-common-conventions プラグインを利用しています。
そして example.java-common-conventions.gradle でプロジェクト共通の定義がされています。
plugins {
id 'java'
}
repositories {
jcenter()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
tasks.named('test') {
useJUnitPlatform()
}
buildSrc
Gradle は実行されたときに buildSrc ディレクトリを確認し、そしの中のコードを自動的にコンパイル・テストを行い、ビルドスクリプトのクラスパスに追加します。
この buildSrc ビルドを使用して、必須ビルドロジックと共通ビルドロジックなどを整理できます。
通常、マルチプロジェクト内のサブプロジェクトは、ある特徴別で構成されます。 この特徴は、パブリック・ライブラリ であったり、内部ライブラリであったり、ウェブサービスであったり、ドキュメント生成コードであったり様々です。
これらの特徴は、サブプロジェクトのタイプを示しており、言い換えれば、サブプロジェクトのタイプがそのサブプロジェクトの特徴を示しているということになります。
Gradle ではプロジェクトの特徴を整理する方法としてプラグインシステムを使っています。一般的な Java プロジェクトであれば java プラグイン、アプリケーションであれば application プラグインを適用してプロジェクトを構成します。
buildSrc ディレクトリに convention プラグインとして各種の特徴を定義し、各サブプロジェクトでそのプラグインを適用することでビルドロジックを整理できます。つまりプラグインを適用することで、それぞれのサブプロジェクトを特徴付けることができます。
先の例では example.java-common-conventions という共通の convention プラグインと、example.java-library-conventions というライブラリ用の共通の convention プラグイン、そして example.java-application-conventions というアプリケーション用のconvention プラグインを定義し、それぞれのサブプロジェクトに適用することで、そのサププロジェクトのタイプを形付けることができるようになっています。
なお、convention プラグインにはケバブ・ケース(全て小文字で - で連結)で名前を付けることが推奨されています。
- 作者:Muschko, Benjamin
- 発売日: 2014/03/09
- メディア: ペーパーバック
- 作者:Ikkink, Hubert Klein
- 発売日: 2016/05/30
- メディア: Kindle版