Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle fat jar does not contain libraries [duplicate]

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?

like image 985
Harold L. Brown Avatar asked May 18 '20 08:05

Harold L. Brown


People also ask

How do you make a fat jar in Gradle?

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.

What is a fat jar?

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.

What is Fatjar in Gradle?

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.

What is a Gradle configuration?

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.


1 Answers

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.

like image 127
Bjørn Vester Avatar answered Sep 26 '22 21:09

Bjørn Vester