Kotlin JVM App missing "main manifest attribute"

(Kregap) #1

I want to write simple Kotlin JVM CLI app.
After reading documentation of

gradle init

I used the following command:
gradle init --dsl kotlin --package tools.instrumented_tests_runner --test-framework kotlintest --type kotlin-application
I am using Gradle 5.3.1.

Project was generated successfully.
Then I run ./gradlew jar which generated .jar unfortunately trying to run given JAR file output is:
no main manifest attribute, in build/libs/Instrumented Tests Runner.jar
If I understand correctly it is suggesting missing main class reference in manifest, but actually gradle init did add it there.
This is how build.gradle.kts looks like:

 * This file was generated by the Gradle 'init' task.
 * This generated file contains a sample Kotlin application project to get you started.

plugins {
    // Apply the Kotlin JVM plugin to add support for Kotlin on the JVM.

    // Apply the application plugin to add support for building a CLI application.

repositories {
    // Use jcenter for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.

dependencies {
    // Use the Kotlin JDK 8 standard library.

    // Use the Kotlin test library.

    // Use the Kotlin JUnit integration.

application {
    // Define the main class for the application.
    mainClassName = "tools.instrumented_tests_runner.AppKt"

What am I missing?


(Bartłomiej Hołota) #2

Jar file needs manifest configuration, especially to know where is main function. Sometimes is also nice to build-in all dependencies in single jar instead of passing those through class path:

tasks {
  withType<Jar> {
    manifest {
      attributes["Main-Class"] = application.mainClassName
  // here zip stuff found in runtimeClasspath:
  from(configurations.runtimeClasspath.get().map {if (it.isDirectory) it else zipTree(it)})

To build ‘fat jar’ you can look into plugins like shadowJar.

1 Like

(Kregap) #3

‘fat jar’ info helped a lot. Thanks to this , your snippet and a snippet found for Kotlin DSL I managed to make it work with following code addition:

tasks.withType<Jar>() {
    manifest {
        attributes["Main-Class"] = "tools.instrumented_tests_runner.AppKt"
    configurations["compileClasspath"].forEach { file: File ->