はじめに
組み込みのタスク 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
- メディア: ペーパーバック
Gradle Effective Implementations Guide - Second Edition (English Edition)
- 作者:Ikkink, Hubert Klein
- 発売日: 2016/05/30
- メディア: Kindle版