In a previous post, we learned how to created a fat jar using Gradle. To recap, a fat jar is one with all the classes along with the dependent jars bundled in one single jar file.

So far, so good, but there one additional step you need to take if you want to turn the jar file into an executable one: you'll have to specify the main class which needs to be executed when running the jar file.

If you don't and you want to execute your jar file, you'll get:

java -jar build/libs/kotlin-gpx-1.0-SNAPSHOT.jar
no main manifest attribute, in build/libs/kotlin-gpx-1.0-SNAPSHOT.jar

To fix this, you can specify the main class for the jar file by adding the following to your build.gradle.kts build file:

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "MainKt"
    }
}

Don't forget to rebuild your jar after this and you'll be able to execute the jar file now:

$ ./gradlew runWithJavaExec

> Task :runWithJavaExec
08:36:08.682 [main] INFO Main - <be.yellowduck.gpx.Document path=src/test/resources/Gravelgrinders_Gent_4.gpx>
08:36:08.684 [main] INFO Main - Gravelgrinders Gent 4
08:36:08.686 [main] INFO Main - Elapsed: 583ms

BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date

To make it easier to run the jar, I've added an extra gradle task in my build.gradle.kts build file which runs the jar file along with the correct classpath:

tasks.register<JavaExec>("runWithJavaExec") {
    description = "Run the main class with JavaExecTask"
    main = "MainKt"
    classpath = sourceSets["main"].runtimeClasspath
}