Gradle & Groovy - Error: Could not find or load main class

10GritSandpaper :

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
tim_yates :

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'

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=91310&siteId=1