はじめに
Gradle Kotlin DSL もいろいろと変わっており、2022年における Kotlin アプリケーション向けの Build.gradle.kts の定義をまとめます。
Gradle は以下のバージョンを使用します。
$ gradle -v Gradle 7.3
Kotlin は、2021年11月16日にリリースされた Kotlin 1.6 を使うものとします。
Build.gradle.kts
基本的な build.gradle.kts
の構成は以下の様になります。
plugins { kotlin("jvm") version "1.6.0" application } repositories { mavenCentral() } kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17)) } } dependencies { testImplementation(kotlin("test")) } tasks.test { useJUnitPlatform() } application { mainClass.set("app.AppKt") }
以下詳細を見ていきます。
kotlin()
org.jetbrains.kotlin
のグループIDは、Kotlin DSL の kotlin()
で簡略化できます。
kotlin("jvm") version "1.6.0"
これは以下と同義となります。
id("org.jetbrains.kotlin.jvm") version "1.6.0"
kotlin() は、GenerateKotlinDependencyExtensions.kt から自動生成される、PluginDependenciesSpec の拡張関数で、以下のテンプレートから生成されます。
/** * Applies the given Kotlin plugin [module]. * For example: `plugins { kotlin("jvm") version "$embeddedKotlinVersion" }` * Visit the [plugin portal](https://plugins.gradle.org/search?term=org.jetbrains.kotlin) to see the list of available plugins. * @param module simple name of the Kotlin Gradle plugin module, for example "jvm", "android", "kapt", "plugin.allopen" etc... */ fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec = id("org.jetbrains.kotlin.${'$'}module")
なお、以下のような古いプラグインの適用は、問題があるため使用しないでください。
apply plugin: 'kotlin'
標準ライブラリ(stdlib)の依存
Kotlin 1.4.0 からは dependencies に標準ライブラリ(stdlib)の依存を追加する必要はありません。
Kotlin Gradle plugin と同じバージョンの標準ライブラリが自動的に追加されます。
標準ライブラリが自動的に追加を抑止するには kotlin.stdlib.default.dependency=false
を使います。
旧来は以下のように標準ライブラリ(kotlin-stdlib-jdk8 など)の依存を追加していましたが、現在は不要です。
dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") }
Java ツールチェーンサポート
Kotlin 1.5.30 からは、Gradle 6.7 で追加された Java toolchains support が利用できます。
kotlin
extension 経由で、以下のように指定できます。
kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17)) } }
java
extension 経由で以下のように指定しても同様に機能します。
java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } }
ツールチェーンを構成した場合、kotlinOptions.jvmTarget
で明示的にターゲットバージョンが指定されていなければ、ツールチェーンで指定した JDK のバージョンが jvmTarget に設定されます(Kotlin 1.6.0 からは、JVM 17 に対応するバイトコードバージョンのクラスを生成できるようになりました)。
kotlinOptions.jvmTarget
は以下のように指定することができますが、ツールチェーンを使うのが良いでしょう。
tasks { compileKotlin { kotlinOptions.jvmTarget = "11" } compileTestKotlin { kotlinOptions.jvmTarget = "11" } }
kotlin.testAPI
以前は以下のように指定することが多かったですが、
dependencies { testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") }
以下だけ指定すれば十分です。
dependencies {
testImplementation(kotlin("test"))
}
Kotlin プラグインにより、ソースセットに依存関係として kotlin-test が追加されると、
kotlin-test-common
と kotlin-test-annotations-common
に加え、JVM ソースセットの場合は kotlin-test-junit
(JSソースセットの場合はkotlin-test-js
)が依存に追加されます。
デフォルトでは、JUnit4 が選択されます。JUnit5を使う場合は以下とします。
tasks.test { useJUnitPlatform() }
なお、TestNG を使う場合は以下を設定します。
tasks.test { useTestNG() }
org.gradle.api.tasks.testing.Test が参考になります。
JavaFX アプリケーション
一例として、Kotlin で JavaFX アプリケーションを作る場合の定義を見ておきましょう。
plugins { kotlin("jvm") version "1.6.0" id("org.openjfx.javafxplugin") version "0.0.10" application } repositories { mavenCentral() } kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17)) } } dependencies { testImplementation(kotlin("test")) } tasks.test { useJUnitPlatform() } application { mainClass.set("app.AppKt") } javafx { modules("javafx.controls", "javafx.fxml") }
src.main.kotlin.app.App.kt
は以下のように定義します。
package app import javafx.application.Application import javafx.event.ActionEvent import javafx.event.EventHandler import javafx.stage.Stage import javafx.scene.Scene import javafx.scene.control.Button import javafx.scene.layout.StackPane class App : Application() { override fun start(primaryStage: Stage) { val btn = Button() btn.text = "Button" btn.onAction = EventHandler<ActionEvent> { println("Hello World!") } val root = StackPane() root.children.add(btn) val scene = Scene(root, 300.0, 250.0) primaryStage.title = "Hello World!" primaryStage.scene = scene primaryStage.show() } } fun main(args: Array<String>) { Application.launch(App::class.java, *args) }
以下のウィンドウが立ち上がり、ボタンクリックでコンソールに 「Hello World!」を出力します。
まとめ
変化が早く、検索では古い情報が多く見られるため、Gradle Kotlin DSL のイマドキの定義について記しました。