Gradle - no main manifest attribute
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.
- 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 jar
s
When a mainClassName
property set, then:
-
$ ./gradlew run
will launch themain
method in the class specified in the attribute - the
zip
/tar
archive built usingdistZip
/distTar
tasks will contain a script, which will launch themain
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 ''
}