Gradleの使い方¶
2024-03-24時点のGradle最新バージョンは 8.7 です。
はじめに¶
Javaは仮想マシン(仮想CPU)上で実行されるバイトコードを生成するコンパイラ言語で、Linux OS、Mac OS、Windows OSなど色々な計算機上で実行されるプログラムを生成します。そのため、開発環境も色々な計算機上で動くものが提供されています。そこで、Javaで開発する際に特定のOSや特定の開発環境(IDE)に依存しない汎用的なビルドツールが整備されてきました。
GradleもOSやIDEに依存しない汎用的なビルドツールとして登場しました。それまでのAntやMavenとの違いは、ビルド定義の記述をXMLではなくスクリプトで記述できる点、スクリプトなのでゴリゴリと実行コードを書くことができる点にあります。
Gradleでは、ビルド定義をGroovyまたはKotlinのスクリプトとして記述します。初期のGradleはGroovyのスクリプトでビルド定義を記述するツールとして登場しました。その後、Kotlinのスクリプトでビルド定義を記述することも可能となりました。
また、Gradleではgradle wrapperという方法によって、Gradleでビルドするプロジェクト(ソースファイル、ビルド定義などをまとめたディレクトリ)にGradleツール自身を含めることで、最初にプロジェクトを用意する際にGradleツールを使用すれば、以降はプロジェクトを展開するだけでその中に含まれるGradleツールを使ってビルドが可能になります。つまり、プロジェクトを作成する最初だけGradleツールを用意する必要があり、プロジェクトを利用する環境ではJavaが動けばGradleツールを別途用意する必要がないということです。
この記事では、ビルドスクリプトをKotlinで記述するGradleの使い方を示していきます。(現在書き換え作業中)
Gradleを使う最初の一歩¶
Gradleツールのセットアップ¶
Gradleのプロジェクトを新規に作成するときにGradleツールが必要になります。gradle wrapperを組み込んだGradleプロジェクトを一旦作成した後は、そのGradleプロジェクトを利用する場合は、Gradleプロジェクトの中にGradleツールが含まれるため、ビルド環境においてGradleツールを別途インストールすることは不要です。
Gradle公式サイトのリリースページ(次のURL)にアクセスし、ダウンロードするバージョンの[binary-only]または[complete]のリンクをクリックします。
https://gradle.org/releases/
- binary-only
gradle実行スクリプトファイル、実行に必要なライブラリファイル(JARファイル群)が含まれています。 - complete
binary-onlyに、ドキュメントおよびソースファイルが追加されています。
Windows OS環境へのGradleのインストール¶
インストール先(例、C:\Program Files\Java の下)にダウンロードしたアーカイブファイルを解凍し展開します。
環境変数PATHに、C:\Program Files\Java\gradle-8.4\bin (例)を追加します。
Gradleはシステム(環境変数PATH)上にあるJavaを使用します。また、環境変数JAVA_HOMEを指定してシステム上とは別のJavaを使用することが可能です。
MacOS環境へのGradleのインストール¶
Homebrewを使うと簡単にインストールできます。HomebrewのGradle項参照。
最初のJavaアプリケーション・ビルドプロジェクト¶
まず最初は、コマンドラインで実行するJavaアプリケーションをビルドするGradleプロジェクトを作成します。
Gradleのinitタスクを実行し、必要な設定や雛形を自動生成します。
プロジェクトディレクトリの作成¶
開発するプロジェクトのディレクトリを作成します。
Windows | MacOS |
---|---|
D:\work> mkdir HelloApp D:\work> cd HelloApp D:\work\HelloApp> |
work % mkdir HelloApp work % cd HelloApp HelloApp % |
ひとまず空のディレクトリ D:\work\HelloApp
(MacOS: ~/work/HelloApp
) を用意しました。
gradleのinitタスクを実行¶
- gradle initを8.7で実行 Gradle_init_8.7
ビルドの実行と生成される成果物ディレクトリ・ファイル¶
gradlew.bat を実行します。コマンドラインオプションには、ターゲット(ビルドの場合は build
)を指定します。
D:\work\HelloApp> gradlew build Downloading https://services.gradle.org/distributions/gradle-6.4-bin.zip .........10%..........20%..........30%..........40%.........50%..........60%..........70%..........80%.........90%..........100% BUILD SUCCESSFUL in 23s 7 actionable tasks: 7 executed
ビルド結果次のディレクトリ・ファイルが生成されます。
C:\work\HelloApp\app ├─build ├─classes │ └─java │ ├─main │ │ └─com │ │ └─torutk │ │ └─hello │ │ App.class │ │ │ └─test │ └─com │ └─torutk │ └─hello │ AppTest.class │ ├─distributions │ app.tar │ app.zip │ ├─generated │ └─sources │ ├─annotationProcessor │ │ └─java │ │ ├─main │ │ └─test │ └─headers │ └─java │ ├─main │ └─test ├─libs │ app.jar │ ├─reports │ └─tests │ └─test │ │ index.html │ │ │ ├─classes │ │ com.torutk.hello.AppTest.html │ │ │ ├─css │ │ base-style.css │ │ style.css │ │ │ ├─js │ │ report.js │ │ │ └─packages │ com.torutk.hello.html │ ├─scripts │ app │ app.bat │ ├─test-results │ └─test │ │ TEST-com.torutk.hello.AppTest.xml │ │ │ └─binary │ output.bin │ output.bin.idx │ results.bin │ └─tmp ├─compileJava │ │ source-classes-mapping.txt │ ├─compileTestJava │ │ source-classes-mapping.txt │ ├─jar │ │ MANIFEST.MF │ └─test
プログラムの実行¶
runタスクでプログラムを実行します。
D:\work\HelloApp> gradlew run > Task :app:run Hello world! BUILD SUCCESSFUL in 3s 2 actionable tasks: 1 executed, 1 up-to-date D:\work\HelloApp>
buildタスクで生成されたjarファイルをjavaコマンドから実行することも可能です。
実行可能JARファイルは生成されませんので、以下の実行は失敗します。
D:\work\HelloApp> java -jar build\libs\HelloApp.jar
Hello world.
D:\work\HelloApp>
プログラムの実行時にコマンドライン引数を渡す¶
Javaプログラムにコマンドライン引数を渡すには、gradleのrunタスクの後に--argsオプションでコマンドライン引数の全体の文字列を指定します。
D:\work\HelloApp> gradlew run --args="--x=200 --y=300" :
ビルド生成物の削除(クリーン)¶
ビルドによって生成されたディレクトリ・ファイルを削除します。
D:\work\HelloApp> gradlew clean BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed D:\work\HelloApp>
ユニットテストの実行¶
testタスクでユニットテストを実行します。実行結果はレポートファイルに出力されます。
D:\work\HelloApp> gradlew test BUILD SUCCESSFUL in 2s 3 actionable tasks: 3 executed D:\work\HelloApp>
テスト結果は次に生成されます。D:\work\HelloApp\build\reports\tests\test\index.html
ブラウザに表示させたものは次です。
次の一歩¶
ライブラリを使用する¶
Mavenリポジトリを指定する¶
Sonatype社 が提供するソフトウェア配布サービス Central Repository で、mavenのデフォルトのリポジトリです。Central Repository 上のライブラリを利用するときは次のように定義します。
repositories { mavenCentral() }
他の定義済みリポジトリ
独自のリポジトリを使用するときは、そのリポジトリのURLを指定します。
repositories { maven { url = uri("http://repo.example.com/maven2") } }
ローカルマシン上のファイルを指定する¶
ローカルマシンに配置したライブラリを使用することができます。
flatDir でライブラリを置くディレクトリをリポジトリ指定する方法¶
リポジトリ指定でflatDirを用いてライブラリを収めたフォルダを指定します。
repositories { flatDir { dirs("relative/to/dir", "/absolute/to/dir", "$junit5") } }
junit5 プロパティは、gradle.propertiesファイルやコマンドラインから指定します。
- gradle.properties
junit5 = C:/Program Files/Java/junit5
ピリオドを含むプロパティ名を使用すると、例えば ${junit5.dir}
の様に参照するとエラーとなります。ピリオドがメソッド呼び出し式と扱われるためです。この場合は、次のいずれかの指定をして回避します。
dirs getProperty("junit5.dir")
dirs "${property('junit5.dir')}"
dirs "${project.'junit5.dir'}"
fileTreeでライブラリのディレクトリとファイル名を指定する方法¶
依存関係指定でfileTreeを用いてライブラリファイルのディレクトリと名前を指定します。
dependencies {
implementation(fileTree(mapOf("dir" to "javafx-gadgetsupport/dist", "include" to listOf("*.jar")))
}
ディレクトリ指定は相対パス、絶対パスの指定が可能です。
使用するライブラリを指定する¶
dependencies { implementation("org.slf4j:slf4j-api:1.7.13") testImplementation("junit:junit:4.12") }
コンパイル時および実行時の双方に使用するライブラリは、implementation
で名称を指定します。
テストのコンパイル時およびテストの実行時に使用する(開発対象プログラムの中では使用しない)ライブラリは、testImplementation
で名称を指定します。
その他、compileOnly
、runtimeOnly
、testCompileOnly
、testRuntimeOnly
、api
などの指定があります。
従来使っていたcompile
、runtime
、testCompile
、testRuntime
は非推奨となっており、今後のバージョンで使用できなくなります。
Javaのバージョン指定¶
Javaのソースコード記述、クラスファイルのバージョン指定¶
ソースファイルの記述(言語仕様)バージョン、およびコンパイル後のクラスファイルのバージョンを指定します。
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
ビルドで使う各種ツールのJDKバージョン指定¶
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
文字コードの指定¶
JDK 17までは、Java実行環境のデフォルトエンコーディングがシステム(OS)のエンコーディングとなるので、ソースファイルの文字コードがシステムのエンコーディングと異なる場合は、Javaコンパイラがソースファイルを正しく読み込めないので、コンパイルオプションにエンコーディング指定を追加する必要があります。
例えば、JavaソースファイルをUTF-8エンコーディングで記述し、Windows OS日本語版(エンコーディングはCP932/Windows_31J)でJavaコンパイラを実行すると、ASCIIコードの文字(UTF-8の1バイト文字)以外の文字がエラーとなってしまいます。
Gradleでは、幾つか方法がありますが、以下が柔軟に対応できます。
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
JDK 18以降で、ソースファイルをUTF-8エンコーディングで記述している場合は、JavaコンパイラがUTF-8エンコーディングとして動くので、このエンコーディング指定は不要となります。
JVMオプション指定¶
アプリケーション実行時にjavaコマンドのオプションを指定する¶
application {
applicationDefaultJvmArgs = listOf("-Dgreeting.language=en")
}
JPMSのモジュール対応¶
モジュール対応JAR¶
Gradle 7.0からこの記述は不要となりました。
java {
modularity.inferModulePath = true
}
この設定で、モジュール対応JARライブラリ参照をモジュールパスとして扱われます。
メインクラスを持つモジュール対応JAR¶
application {
mainModule = "org.gradle.sample.app" // name defined in module-info.java
mainClass = "org.gradle.sample.Main"
}
参考¶
Java 9 Jigsaw support #890
Building JPMS Modules with Gradle (Youtube)
ソースディレクトリの構成を変更¶
デフォルトでは、Javaのソースファイルは src/main/java ディレクトリの下に置かれている前提となっています。また、ソースファイル以外のリソースファイルは src/main/resources ディレクトリに置かれる前提となっています。
これを変更する場合、例えばJavaソースファイルおよびリソースファイルをともに src ディレクトリ下に置くには、sourceSets を定義します。
sourceSets {
main {
java.srcDir("src")
resources.srcDir("src")
}
}
サンプル等¶
単一モジュールのGradleプロジェクト¶
複数モジュールのGradleプロジェクト¶
ユニットテスト¶
JUnit 5¶
- [#116] GradleでJUnit5テストをローカルマシンで実施する
応用¶
依存するライブラリをダウンロードする¶
参照:調査チケット #79
Gradleでは依存するライブラリを、実行した環境のキャッシュディレクトリ(ユーザー固有のディレクトリで、Windows上であれば%USERPROFILE%\.gradle\caches\modules-2\files-2.1\
の下、caches以下のディレクトリ名はGradleのバージョンにより変わるかも)に保持します。
ここにはその環境で過去実施したビルドで使用した依存ライブラリが一緒くたに置かれるので、あるライブラリとその依存ライブラリだけを抽出したいときには対応に苦慮します。
そこで、依存するライブラリをダウンロードする専用のビルド定義を記述し必要なものだけダウンロードします。
依存するライブラリのダウンロード定義¶
apply plugin: 'java' def libDir = 'lib' repositories { mavenCentral() } dependencies { compile 'org.jvnet.com4j:com4j:2.1' } task deleteDeps(type: Delete) { delete libDir } task copyDeps(type: Copy, dependsOn: deleteDeps) { from configurations.testRuntime into libDir }
dependencies には、ビルドするときに定義するライブラリの記述と同様にダウンロードしたいライブラリを記述します。
コピータスク(copyDeps)で、testRuntimeを指定しているのは、依存するライブラリの範囲を最大にしているためです。ここをcompileと指定すればコンパイルに必要なものだけダウンロードします(その場合、実行時に必要なライブラリが抜ける可能性があります)。
Gradleのバージョンを更新する¶
Gradleプロジェクトでwrapperを使用しているときのgradleバージョン更新¶
- 現在のGradleプロジェクトが使用するGradleバージョンを確認
D:\work\myproj> gradlew -v ------------------------------------------------------------ Gradle 6.5.1 ------------------------------------------------------------ :
- Gradleのリリース状況を次のURLで確認
https://gradle.org/releases/
- Gradleプロジェクトのwrapperで使用するgradleバージョンを更新
最新のリリースバージョンである6.8.3に更新するときの例を次に示します。D:\work\myproj> gradlew wrapper --gradle-version=6.8.3
このコマンドは、gradle/wrapper/gradle-wrapper.properties ファイルを更新します。 - Gradleの本体、バッチ・スクリプト更新を更新するには次を実行
D:\work\myproj> gradlew wrapper
サーブレットアプリケーションの作成¶
Gradleではサーブレットアプリケーションを作成するwarプラグインが提供されています。ただし、warプラグインを使うGradleプロジェクトは、initでは生成できません。
Gradleの機能¶
コマンド¶
UP-TO-DATEとなるタスクを実行したい¶
proj$ ./gradlew jlinkZip --rerun
cleanタスクを実行しても、タスクがUP-TO-DATEとなることがありました。タスクの実行要否の判断で、インプットとなるファイルに変更がない場合にアウトプットが存在しなくてもUP-TO-DATEとなるケースがあるようです。gladleコマンドに実行したいタスクと--rerunオプションを指定することで、UP-TO-DATEと判断されるタスクを実行します。
ビルド設定¶
ビルド定義(build.gradle等)の外部から設定を行います。ユーザー/特定のビルド環境に固有の設定をビルドに適用する場合に使用します。
- Javaのシステムプロパティとして与える
- Gradleプロパティとして与える
- 環境変数で与える
システムプロパティ¶
システムプロパティとして定義した値をビルドで利用します。定義方法は- gradleのコマンドラインで、-Dオプションで指定。例:
gradlew -Dmy.data.dir=D:\data\myapp
- gradle.properteisファイルに、systemProp.の後ろにキーと価を指定。例:
systemProp.my.data.dir=D:\data\myapp
gradleプロパティ¶
プロジェクトディレクトリに置いたgradle.properties
ファイル、およびユーザーのホームディレクトリ下の gradle\gradle.properties
ファイルに記載します。
systemProp.my.data.dir=D:\data\myapp
プラグイン¶
Build Init プラグイン¶
Gradleビルドプロジェクトの新規作成を行うプラグインです。
- ビルド種類(build type)
- DSL言語(ビルド定義を記述する言語、GroovyかKotlinか)
- ビルド種類がJava系の場合、テストフレームワーク
Java用のビルドでは、次のオプションをコマンドライン指定または対話的に入力します。
オプション名 | オプション指定 | オプションの値 | 備考 |
---|---|---|---|
ビルド種類 | --build-type |
java-application, java-library |
|
DSL言語 | --dsl |
groovy, kotlin |
|
テストフレームワーク | --test-framework |
junit4, junit-jupiter, spock, testng |
|
プロジェクト名 | --project-name |
プロジェクト名 | 成果物(JARファイル等)の名称に使われる |
パッケージ名 | --package |
パッケージ名 | 成果物の代表パッケージ名 |
javaプラグイン¶
Javaのライブラリを作成する際に有用なプラグインです。次のタスクが提供されています。
classes testClasses compileJava compileTestJava jar test javadoc clean assemble check bulid buildNeeded buildDependents processResources processTestResources uploadArchives
新規にプロジェクトを作成するときのテンプレート生成も提供されています。
work$ gradle init --type java-library :wrapper :init BUILD SUCCESSFUL Total time: 1.62 secs work$ ls build.gradle* gradle/ gradlew* gradlew.bat* settings.gradle* src/
生成されるbuild.gradleは次になります(コメントを削除しています)。
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.13'
testCompile 'junit:junit:4.12'
}
javacコンパイルオプション¶
compilerArgsに任意のオプションを記述するとコンパイル時にjavacコマンドのオプションとして適用されます。
Gradle User Manual - CompileOptions
compileJava {
options.compilerArgs.addAll(['--release', '7'])
}
--release
オプションはJDK 9から導入され、Gradleでは6.6から対応予定です。それまでは上述のように汎用のコンパイル引数として指定します。
Add property for setting the `--release` compiler argument - gradle issues #2510
Gradleの記述方法¶
Gradleは、Groovy言語で記述します(その後Kotlin言語で記述することもできるようになりました)。
Groovyの記法メモ¶
Groovy は、一つの事を記述するのに複数の書き方があり、混沌に属する言語です(まるでPerlの再来)。
- メソッド呼び出し式では括弧を省略
- プロパティ風な書き方で、setterメソッドの代わりに代入式を書ける
- 名前付き引数(これと括弧の省略を合わせると何が何だかな記法になる)
- 波括弧でクロージャー(コードブロック)
Gradleのバージョン¶
バージョンの変遷(トピック)¶
- v8.5
JDK 21への完全対応 - v8.4
JDK 21を使ったビルド・テストに対応(Gradle自身のJDK 21上での実行は未サポート) - v8.3
JDK 20への完全対応 - v7.3
JDK 17を使うプロジェクトのビルド、JDK 17上でGradleの実行対応 - v7.0 2021-04-9
JDK 16対応、Groovy 3に移行 - v6.4.1 2020-05-15
Javaモジュールシステムに対応