I have created a simple Gradle Java project. The build.gradle
file looks like this:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.10'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}
test {
useJUnitPlatform()
}
task customFatJar(type: Jar) {
archiveBaseName = 'fat-jar'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
I am creating the fat jar
according to https://www.baeldung.com/gradle-fat-jar.
However, the resulting jar does not contain the commons-lang3
library. It only contains the project's class files.
Why isn't my library included in the fat jar
?
Build a Fat JAR To build a Fat JAR, open the terminal and execute the shadowJar task provided by the Shadow plugin. When this build completes, you should see the ***-all. jar file in the build/libs directory. For example, for the fatjar project a file name is fatjar-all.
An uber-JAR—also known as a fat JAR or JAR with dependencies—is a JAR file that contains not only a Java program, but embeds its dependencies as well. This means that the JAR functions as an “all-in-one” distribution of the software, without needing any other Java code.
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.
A “configuration” is a named grouping of dependencies. A Gradle build can have zero or more of them. A “repository” is a source of dependencies. Dependencies are often declared via identifying attributes, and given these attributes, Gradle knows how to find a dependency in a repository.
The guide from Baeldung is outdated. I suggest following the guide in the official user guide instead: https://docs.gradle.org/current/userguide/building_java_projects.html#sec:java_packaging
They are currently suggesting this:
task uberJar(type: Jar) {
archiveClassifier = 'uber'
from sourceSets.main.output
dependsOn configurations.runtimeClasspath
from {
configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }
}
}
You can customize the name like you already did, if you don't like using properties like archiveClassifier
.
If you are interested in why the Baeldung version doesn't work for you, it is because they collect dependencies from the deprecated configuration called compile
. You are using the newer implementation
instead, so compile
is empty. However, instead of simply changing compile
to implementation
, it is recommended to use runtimeClasspath
(like in the user guide) as this will correctly handle dependencies that are scoped to only the compile phase or as runtime only. While you don't have any of those now, you may in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With