Building an uberjar with Gradle

44,809

Solution 1

Have you tried the fatjar example in the gradle cookbook?

What you're looking for is the shadow plugin for gradle

Solution 2

I replaced the task uberjar(.. with the following:

jar {
    from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }

    manifest {
        attributes 'Implementation-Title': 'Foobar',
                'Implementation-Version': version,
                'Built-By': System.getProperty('user.name'),
                'Built-Date': new Date(),
                'Built-JDK': System.getProperty('java.version'),
                'Main-Class': mainClassName
    }
}

The exclusions are needed because in their absence you will hit this issue.

Solution 3

Simply add this to your java module's build.gradle.

mainClassName = "my.main.Class"

jar {
  manifest { 
    attributes "Main-Class": "$mainClassName"
  }  

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

This will result in [module_name]/build/libs/[module_name].jar file.

Solution 4

I found this project very useful. Using it as a reference, my Gradle uberjar task would be

task uberjar(type: Jar, dependsOn: [':compileJava', ':processResources']) {
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }

    manifest {
        attributes 'Main-Class': 'SomeClass'
    }
}
Share:
44,809
missingfaktor
Author by

missingfaktor

I am no longer active on this site, but if my posts help you and/or you need further help, do let me know on Twitter at @missingfaktor. I will try my best to respond! Note: This profile description was written for StackOverflow, and was copied to all other StackExchange sites as-is.

Updated on July 09, 2022

Comments

  • missingfaktor
    missingfaktor almost 2 years

    I want to build an uberjar (AKA fatjar) that includes all the transitive dependencies of the project. What lines do I need to add to build.gradle?

    This is what I currently have:

    task uberjar(type: Jar) {
        from files(sourceSets.main.output.classesDir)
    
        manifest {
            attributes 'Implementation-Title': 'Foobar',
                    'Implementation-Version': version,
                    'Built-By': System.getProperty('user.name'),
                    'Built-Date': new Date(),
                    'Built-JDK': System.getProperty('java.version'),
                    'Main-Class': mainClassName
        }
    }
    
  • missingfaktor
    missingfaktor almost 12 years
    Thank you for the pointer. It helped. Though I hit another issue which was solved by a bit of googling. I'll add another answer expanding on that.
  • lyomi
    lyomi over 9 years
    I think it should use configurations.runtime to include all runtime dependencies
  • gladiator
    gladiator over 9 years
    i needed to add with jar below manifest to get the files in java/main/resources in the uberjar
  • oarsome
    oarsome about 9 years
    It looks like the cookbook now requires a login. As this is exactly what I am looking for, could you paste the recipe in here please?
  • tim_yates
    tim_yates about 9 years
    @tarzan three years later, and I'd now use the shadow plugin github.com/johnrengelman/shadow
  • Hugo Zaragoza
    Hugo Zaragoza about 9 years
    this is very simple and worked the first time (after trying many other "answers": stackoverflow.com/questions/23738676/…
  • tim_yates
    tim_yates about 9 years
    Things change in 3 years. And I'd still use the shadow plugin ;-)
  • Sam Redway
    Sam Redway about 7 years
    but what is that code? What does configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } do?
  • pal
    pal almost 7 years
    @SamRedway configurations.compile.collect collects stuff from compile The ternary lets it pull in both folders and zip-files (like jars) as if they were also folders
  • chris
    chris almost 7 years
    I haven't tried the other versions posted here, but this one works nicely and is nice and simple.
  • Nicholas DiPiazza
    Nicholas DiPiazza over 6 years
    i get Invalid signature file digest for Manifest main attributes when i try this
  • Nicholas DiPiazza
    Nicholas DiPiazza over 6 years
    you need exclude "META-INF/*.SF" exclude "META-INF/*.DSA" exclude "META-INF/*.RSA" like missingfaktor's answer
  • techcraver
    techcraver about 6 years
    That worked for me! Without the exclude part it was killing me with SecurityException and with this fix it works!
  • mkobit
    mkobit almost 6 years
    This answer excludes any runtime or runtimeOnly declared dependencies, which will cause the application to break at runtime.
  • mkobit
    mkobit almost 6 years
    Best to even use the sourceSets.getByName('main').runtimeClasspath
  • Franklin Yu
    Franklin Yu about 5 years
    @mkobit You can replace compile with runtimeClasspath as specified in this answer.
  • lathspell
    lathspell about 5 years
    Does not seem to work with Gradle 5.3.1: "Could not get unknown property 'classesDir' for main classes of type org.gradle.api.internal.tasks.DefaultSourceSetOutput."
  • Gili
    Gili almost 5 years
    shadowjar isn't very well-maintained. See github.com/johnrengelman/shadow/issues/476 and other critical issues that have gone unfixed for months.
  • user64141
    user64141 over 4 years
    anybody know what this would look like in kotlin (for the build.gradle,kts file) ?
  • aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa about 4 years
    it gives me java.lang.UnsupportedOperationException