Reputation: 4436
I can run my project using gradle run
, but I can't run the jar file using java -jar
. I've recreated the error with this sample project: link to project on GitHub
This is the output from running the project via gradlew
$ ./gradlew run
> Task :run
Hello world.
BUILD SUCCESSFUL in 4s
This is the output from running the project java -jar
$ ./gradlew build
BUILD SUCCESSFUL in 6s
$ java -jar build/libs/emailer.jar
Error: Could not find or load main class us.company.emailer.App
But when I unzip
the jar
, I can see App.class
user@computer:../libs$ unzip emailer.jar
Archive: emailer.jar
creating: META-INF/
inflating: META-INF/MANIFEST.MF
creating: us/
creating: us/company/
creating: us/company/emailer/
inflating: us/company/emailer/App.class
Here's the build.gradle
plugins {
id 'groovy'
id 'application'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation 'org.codehaus.groovy:groovy-all:2.5.6'
testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
compile 'org.apache.commons:commons-email:1.5'
}
mainClassName = 'us.company.emailer.App'
jar {
manifest {
attributes(
'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
'Main-Class': 'us.company.emailer.App'
)
}
}
sourceSets.main.java.srcDirs = ['src/main/groovy']
Here's the App.groovy
package us.company.emailer
class App {
String getGreeting() {
return 'Hello world.'
}
static void main(String[] args) {
println new App().greeting
}
}
EDIT: Adding MANIFEST.MF
in response to the comment from @tkruse
Manifest-Version: 1.0
Class-Path: commons-email-1.5.jar javax.mail-1.5.6.jar activation-1.1.
jar
Main-Class: us.company.emailer.App
Upvotes: 4
Views: 5633
Reputation: 171194
The problem is the classpath. If you look inside the META-INF/MANIFEST.mf
file, you can see it's set to:
Class-Path: commons-email-1.5.jar javax.mail-1.5.6.jar activation-1.1.
jar
When java runs, it has no idea where any of these things are, it also requires the groovy runtime in order to understand your groovy code.
The simplest way of doing this is to bundle all your dependencies into a "fat-jar", and the simplest way of doing this with Gradle is the excellent Shadow-jar plugin.
If you add the following to your plugins
block in build.gradle
:
id 'com.github.johnrengelman.shadow' version '5.0.0'
(You can delete the jar
block and the line that manipulates the sourceSets)
Then run ./gradlew shadowJar
You'll get a jar file emailer-all.jar
Which can be run:
$ java -jar build/libs/emailer-all.jar
Hello world.
For completeness, here's the complete build.gradle file:
plugins {
id 'groovy'
id 'application'
id 'com.github.johnrengelman.shadow' version '5.0.0'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation 'org.codehaus.groovy:groovy-all:2.5.6'
testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
implementation 'org.apache.commons:commons-email:1.5'
}
mainClassName = 'us.company.emailer.App'
Upvotes: 4