1. Overview

In this quick article, we'll cover creating a “fat jar” in Gradle.

Basically, a fat jar (also known as uber-jar) is a self-sufficient archive which contains both classes and dependencies needed to run an application.

2. Initial Setup

Let's start with a simple build.gradle file for a Java project with two dependencies:

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
    compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
}

3. Using the Jar Task From the Java Plugin

Let's start with modifying the jar task from the Java Gradle plugin. By default, this task produces jars without any dependencies.

We can overwrite this behavior by adding a few lines of code. We need two things to make it work:

  • a Main-Class attribute in the manifest file
  • Include dependencies jars

Let's add few modifications to the Gradle task:

jar {
    manifest {
        attributes "Main-Class": "com.baeldung.fatjar.Application"
    }

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

4. Creating a Separate Task

If we want to leave the original jar task as it is, we can create a separate one which will do the same job.

The following code will add a new task called customFatJar:

task customFatJar(type: Jar) {
    manifest {
        attributes 'Main-Class': 'com.baeldung.fatjar.Application'
    }
    baseName = 'all-in-one-jar'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

5. Using Dedicated Plugins

We can also use existing Gradle plugins in order to build a fat jar.

In this example we'll use the Shadow plugin:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.1'
    }
}

apply plugin: 'java'
apply plugin: 'com.github.johnrengelman.shadow'

Once we apply the Shadow plugin, the shadowJar task will be ready to use.

6. Conclusion

In this tutorial, we presented a few different ways of creating fat jars in Gradle. We overrode the default jar task, created a separated task and used the shadow plugin.

Which approach is recommended? The answer is – it depends.

In simple projects, it's enough to override the default jar task or create a new one. But as the project grows we highly recommend to use plugins, because they already have solved more difficult problems like conflicts with external META-INF files.

As always, the full implementation of this tutorial can be found over on GitHub.