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.
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.
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:
$ ./gradlew runwill launch themainmethod in the class specified in the attribute- the
zip/tararchive built usingdistZip/distTartasks will contain a script, which will launch themainmethod 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.