Gradle - no main manifest attribute

I'm building a JAR file with Gradle. When I try to run it I get the following error

no main manifest attribute, in RxJavaDemo.jar

I tried manipulating the manifest property but I think I'm forgetting to add the dependencies or something to it. What exactly am I doing wrong?

apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'demo.MainDashboard'
dependencies { compile files ("H:/Processes/Development/libraries/hikari-cp/HikariCP-2.4.1.jar") compile files ("H:/Processes/Development/libraries/controls-fx/controlsfx.jar") compile files ("H:/Processes/Development/libraries/database_connections/sqlite-jdbc-3.8.6.jar") compile files ("H:/Processes/Development/libraries/guava/guava-18.0.jar") compile files ("H:/Processes/Development/libraries/rxjava/rxjava-1.0.12.jar") compile files ("H:/Processes/Development/libraries/rxjava-extras/rxjava-extras-0.5.15.jar") compile files ("H:/Processes/Development/libraries/rxjavafx/RxJavaFX-1.0.0-RC1-SNAPSHOT.jar") compile files ("H:/Processes/Development/libraries/rxjavaguava/rxjava-guava-1.0.3.jar") compile files ("H:/Processes/Development/libraries/rxjava-jdbc/rxjava-jdbc-0.6.3.jar") compile files ("H:/Processes/Development/libraries/slf4j/slf4j-api-1.7.12.jar") compile files ("H:/Processes/Development/libraries/tom-commons/tom-commons.jar")
}
sourceSets { main.java.srcDir "src/main/java" main.resources.srcDir "src/main/resources"
}
jar { manifest { attributes( "Class-Path": configurations.compile.collect { it.getName() }.join(' ')) } from configurations.compile.collect { entry -> zipTree(entry) }
}

4 Answers

Try to change your manifest attributes like:

jar { manifest { attributes( 'Class-Path': configurations.compile.collect { it.getName() }.join(' '), 'Main-Class': 'hello.HelloWorld' ) }
}

And then just change 'hello.helloWorld' to '<your packagename>.<the name of your Main class>' (where your Main class has a main method). In this case, you make in your manifest an attribute, which point to this class, then a jar is running.

6

To make the jar file executable (so that the java -jar command works), specify the Main-Class attribute in MANIFEST.MF.

In Gradle, you can do it by configuring the jar task.

  • for Groovy DSL see these answers ([1], [2])
  • for Kotlin DSL you can use the following code snippet:
tasks.withType<Jar> { manifest { attributes["Main-Class"] = "com.caco3.Main" }
}

Why mainClassName does not work as expected?

Or why mainClassName does not specify the attribute in the manifest?

The mainClassName property comes from the application plugin. The plugin:

makes it easy to start the application locally during development, and to package the application as a TAR and/or ZIP including operating system specific start scripts.

So the application plugin does not aim at producing executable jars

When a mainClassName property set, then:

  1. $ ./gradlew run will launch the main method in the class specified in the attribute
  2. the zip/tar archive built using distZip/distTar tasks will contain a script, which will launch the main method of the specified previously class.

Here is the line of shell script setting the main class:

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"

FWIW - I used the following jar task to assemble all my compile dependencies into the jar file, and used the above recommendation to get the class-path properly set

apply plugin: 'java-library'
jar { manifest { attributes( 'Class-Path': configurations.compile.collect { it.getName() }.join(' '), 'Main-Class': 'your.main.class.goes.here' ) } // You can reference any part of the dependency configurations, // and you can have as many from statements as you need from configurations.compile // I just copied them into the top of the jar, so it looks like the eclipse exported // runnable jar, but you could designate a lib directory, and reference that in the // classpath as "lib/$it.name" instead of it.getName() into ''
}

To complement Denis Zavedeev answer, here are more ways for Kotlin DSL (build.gradle.kts):

tasks.jar { manifest.attributes["Main-Class"] = "com.example.MyMainClass"
}
tasks.jar { manifest { attributes["Main-Class"] = "com.example.MyMainClass" }
}

Side note: to create a runnable fat JAR (also called uber JAR), see this post.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like