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
?
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.