Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gradle: exclude a dependency in making fatJar

There are lots of repeated answers on how to exclude an individual file from a fatJar. Typically, the file is excluded are in META-INF and they are excluded either because of a filename conflict, or because it is a signature copied from a dependency libarar Jar file which isn't valid for the newly created Jar file.

Example for maven: How can I tell which signed jar is causing maven-shade-plugin to fail?

Example for gradle: Removing Jar Signatures in Gradle Build

These solutions, however, only removed the offending file individually.

How can we make a fatJar with a specific dependency library (not individual files in that library) excluded?

For example, in question 36226033, it's easy to exclude the signature copied over from BouncyCastle, but is there a way to exclude the dependency library bcprov-jdk15on-*.jar entirely, so that the user must have the library available in order to execute the generated fat Jar?

This is proven not working:

task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',
                'Implementation-Version': version,
                'Main-Class': 'com.alphawallet.scripttool.Main'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    exclude('**/bcprov-jdk15on-1.62.jar')
    with jar
}

With exclude('**/bcprov-jdk15on-1.62.jar'), the content of that jar file is still copied over to the fat jar generated.

Thanks. The motivation is to ship my Java application to systems that provides their own security library BouncyCastle (e.g. Debian Linux), instead of embeding an unsigned copy of that security library.

like image 473
Tankman六四 Avatar asked Jan 08 '20 08:01

Tankman六四


People also ask

What is a fat jar in Gradle?

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.

How to exclude transitive dependencies in Gradle?

How to exclude transitive dependencies in gradle? This section talks about exclude at runtime and compile time for each dependency exclude runtime dependency: Some times, You have transitive dependencies which are causing conflict with version of direct dependency. This excludes the dependency library from given ouput jar or war file

What is the difference between Maven and Gradle exclusions?

On the upside, Gradle’s exclude handling is, in contrast to Maven, taking the whole dependency graph into account. So if there are multiple dependencies on a library, excludes are only exercised if all dependencies agree on them.

How do you exclude an artifact in Gradle?

Within the closure we call exclude, passing: module the name of the artifact we want to exclude. This is equivalent to the name used to declare a dependency in Gradle. It’s also entirely valid to pass only group or only module to match more generically.


1 Answers

I don't know how excludes and includes works, but I would expect that these configurations work on a class file level, because that what the jar is working on.

It's not working on jars.

I would go for this solution:

task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',
                'Implementation-Version': version,
                'Main-Class': 'com.alphawallet.scripttool.Main'
    }
    baseName = project.name + '-all'
    configurations.compile.findAll { file ->
        // file is of type java.io.File
        // when true, jar file is unziped and added 
        file.name != "bcprov-jdk15on-1.62.jar"
    }.sort { it.name }
            .collect { file ->
                logger.info("Including file: ${file.name}")
                file.isDirectory() ? file : zipTree(file)
            }
    with jar
}
like image 74
Peter Avatar answered Nov 15 '22 03:11

Peter