151

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) }
}
Mahozad
26.4k19 gold badges163 silver badges200 bronze badges
asked Sep 14, 2015 at 14:18

6 Answers 6

200

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.

a.t.
2,9377 gold badges49 silver badges101 bronze badges
answered Sep 14, 2015 at 14:35
Sign up to request clarification or add additional context in comments.

8 Comments

@Stanislav 'Main-Class' value is the main class? What are hello and helloWorld in your example?
@DanielaMaia it's just a full qualified class name, sure it has to be written as hello.HelloWorld, where hello is the package where the HelloWorld class is located
I needed to remove the collect {} portion to get it to work for me. Your code assumes that all dependencies are in the same folder as your main class.
@AutonomousApps How exactly did you do that?
The lastest Gradle version has replaced compile. Instead use: 'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')
|
41

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"
answered Sep 6, 2020 at 18:10

2 Comments

I get that the application plugin doesn't have a goal of creating a runnable jar, but it's still annoying that we have to do these extra steps in Gradle all the time for a runnable jar. It should have everything it needs for a manifest...
Although I suppose the reason is, your jar will be missing dependencies so it's not usually runnable anyway. :)
5

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.

answered Feb 12, 2022 at 14:39

3 Comments

Starting with Gradle 8.x somehow array access for attributes is unavailable.
@YaMiN Are you sure? I tried both of the above code snippets right now with Gradle 8.0 and it seemed to work with no problem.
Yeah I'm sure. I don't know why but after upgrading to Gradle 8.0.2 it gives me No set method providing array access error, however, the project compiles.
1

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 '' 
}
answered May 6, 2019 at 16:17

Comments

0

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
 }
 }
}
answered Dec 3, 2024 at 13:14

Comments

-1

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

enter image description here

enter image description here

p.s. manual starting jar task did not solve my problem in my case

Eugene
3,35723 silver badges25 bronze badges
answered May 22, 2024 at 8:03

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.