gradle: exclude a dependency in making fatJar
Asked Answered
P

1

6

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.

Pedometer answered 8/1, 2020 at 8:59 Comment(0)
S
8

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
}
Shala answered 8/1, 2020 at 9:43 Comment(1)
Your thoughtful answer is greatly appreciated! I am surprised there isn't a direct method to do so.Philbert

© 2022 - 2024 — McMap. All rights reserved.