I’m trying to build an executable jar from an extremely simple Kotlin application. Here is the code:
// org/example/App.kt
package org.example
import kotlin.random.Random
class App {
fun run() {
var x = 0L
for (i in 2..100000) {
x += Random.nextInt(i)
}
println(x)
}
}
fun main() {
App().run()
}
Here is my build.gradle.kts file:
plugins {
alias(libs.plugins.jvm)
application
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.apache.commons:commons-math3:3.6.1")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
}
}
application {
mainClass = "org.example.AppKt"
}
tasks.named<Jar>("jar") {
manifest {
attributes["Manifest-Version"] = "1.0"
attributes["Main-Class"] = "org.example.AppKt"
attributes["Class-Path"] = configurations.compileClasspath.get().joinToString(" ") { it.name }
}
}
When I run the gradle build task, and then run java -jar app/build/libs/app.jar
, I get this output:
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/random/Random
at org.example.App.run(App.kt:9)
at org.example.AppKt.main(App.kt:16)
at org.example.AppKt.main(App.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.random.Random
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 3 more
This is obviously an error in how I’m building the jar, as kotlin.random.Random
is part of the standard library. I’ve searched high and low for information on this error, and everything is either outdated or just does not work for me. If anyone can advise me on what I’m doing wrong, I’d really appreciate it. I don’t think Docker is part of the issue, as I’m unable to run my jar when running the gradle build task directly, but in case it’s at all relevant, here is my Dockerfile as well:
FROM gradle:8.6.0-jdk11-alpine AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon
FROM eclipse-temurin:11-jre
EXPOSE 8080
RUN mkdir /app
COPY --from=build /home/gradle/src/app/build/libs/*.jar /app/docker-test.jar
ENTRYPOINT ["java","-jar","/app/docker-test.jar"]
Historically, I’ve been building my jars using the Ktor plugin’s buildFatJar
task, as I’ve never been able to get Gradle to successfully build a working jar. I’d like to finally learn what I’m doing wrong, and possibly be able to actually build something runnable with Gradle alone.