LoginSignup
1
2

More than 1 year has passed since last update.

Gradle + Kotlinで実行可能な.jarファイルを出力する

Last updated at Posted at 2021-11-23

環境

  • 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)
        }
    }
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2