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:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
implementation 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.runtimeClasspath.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'
}
archiveBaseName = 'all-in-one-jar'
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from { configurations.runtimeClasspath.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 {
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.2"
}
}
plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'java'
}
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.