環境
- Gradle 7.3
- Kotlin 1.6.0
- JDK 11
結論
以下の設定をbuild.gradleに書いておけば問題ないはず。
- メインメソッドの在処
- kotlin-stdlibを.jarファイルに含める
あとは以下のコマンドで実行できる。
$ ./gradlew jar
$ java -jar build/libs/YOUR_PROJECT_NAME.jar
メインメソッドの在処
これが出来ていないと $ java -jar ...
の結果以下のように怒られる。
build/libs/YOUR_PROJECT_NAME.jarにメイン・マニフェスト属性がありません
散々言われてそうだけど、build.gradleに以下の記述を追加すればOK。
jar {
manifest {
attributes 'Main-Class': 'mainメソッドを定義しているクラス名'
}
}
ちなみにパッケージ直下にmainメソッドを定義している場合、mainメソッドを所有しているクラスの名前はファイル名 + "Kt"になる。例えばファイル名が"Entrypoint.kt"だった場合は、"EntrypointKt"になる。
kotlin-stdlibを.jarファイルに含める
いきなり話が逸れるけど、いつからか依存にkotlin-stdlibを書かなくても、Gradleプラグインにkotlinを指定するだけでKotlinが有効になり、IDEで実行可能になっている。
が、これは単にIDE上での話っぽく、.jarファイルで実行するには依然必要である。もし適切に設定していないと、 $ java -jar ...
の結果以下のように怒られる。
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
at MainKt.main(Main.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
これを解決するにはbuild.gradleに以下の記述を追加する。
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib' // コンパイル時に使用
}
jar {
from {
configurations.compileClasspath.collect { // .jarファイルに含める
it.isDirectory() ? it : zipTree(it)
}
}
}