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) }
}
6 Answers 6
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.
8 Comments
collect {} portion to get it to work for me. Your code assumes that all dependencies are in the same folder as your main class.compile. Instead use: 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')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"
2 Comments
To complement Denis Zavedeev answer, here are more ways for Kotlin DSL (build.gradle.kts):
tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
}
Another notation:
tasks.jar {
manifest {
attributes["Main-Class"] = "com.example.MyMainClass"
}
}
Side note: to create a runnable fat JAR (also called uber JAR), see this post.
3 Comments
8.x somehow array access for attributes is unavailable.No set method providing array access error, however, the project compiles.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 ''
}
Comments
Reference this solution effective for Spring 3:
plugins {
id 'maven-publish'
id 'java-library'
}
jar {
enabled = false
}
java {
withSourcesJar()
withJavadocJar()
}
publishing {
publications {
publication(MavenPublication) {
artifact bootJar
from components.java
}
}
}
Comments
If no solution helps you (you tried all previous answers) - try to simply build your spring boot app and IntelliJ idea place .jar to the temp build folder. Only this solution resolved my problem.
You should create a task in your build.gradle file:
baseName - your future .jar file's name
p.s. manual starting jar task did not solve my problem in my case