Hello,
I use some libraries in my Gradle project which have also got other libraries inside them and so on. As a result, I get many duplicate files in my final JAR, e.g. several LICENSE
files or several javax
packages.
I have already found a way to exclude certain files:
jar {
from {
configurations.embed.collect {
exclude '.project'
exclude '.classpath'
exclude 'about.html'
exclude 'LICENSE'
exclude 'NOTICE'
exclude 'LICENSE.txt'
exclude 'NOTICE.txt'
exclude 'META-INF/*'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/DEPENDENCIES'
it.isDirectory() ? it : zipTree(it)
}
}
}
This works fine, however, there are also tons of classes duplicated, e.g.:
:reobfJar FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':reobfJar'.
> java.util.zip.ZipException: duplicate entry: javax/annotation/CheckForNull.class
I’d liked to ask how to exclude a whole directory like javax/
, but I guess classes that directory contains may be essential for some libraries I use. So my question is:
how do I properly handle the “duplicate entry” issue in Gradle?
Is there a way to, for example, just skip this error and simply ignore files that are already present in the JAR or something like that?
My whole build.gradle
file:
buildscript {
repositories {
jcenter()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT'
}
}
repositories {
mavenLocal()
mavenCentral()
}
apply plugin: 'net.minecraftforge.gradle.forge'
version = "1.0.0"
group = "club.pvpnation.forgemod"
archivesBaseName = "pvpn-mod"
sourceCompatibility = 1.8
targetCompatibility = 1.8
minecraft {
version = "1.8.9-11.15.1.2318-1.8.9"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not allways work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "stable_20"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}
configurations {
embed
compile.extendsFrom embed
}
dependencies {
// Embed in JAR
embed group: 'org.reflections', name: 'reflections', version: '0.9.10'
embed group: 'me.darksidecode.kantanj', name: 'kantanj', version: '1.0.0'
// Annotation Processors
/* annotationProcessor - Gradle 5+ */ compile group: 'org.projectlombok', name: 'lombok', version: '1.18.6'
}
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else
from (sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}
// copy everything else, thats not the mcmod.info
from (sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
// https://gist.github.com/matthewprenger/9b2da059b89433a01c1c
task signJar(type: SignJar, dependsOn: reobfJar) {
// gradle.properties
keyStore = project.keyStore // This needs to be a path to the keystore file
alias = project.keyStoreAlias
storePass = project.keyStorePass
keyPass = project.keyStoreKeyPass
inputFile = jar.archivePath
outputFile = jar.archivePath
}
//noinspection GrUnresolvedAccess
build.dependsOn signJar
// Include dependencies in JAR
jar {
from {
configurations.embed.collect {
exclude 'javax'
exclude '.project'
exclude '.classpath'
exclude 'about.html'
exclude 'LICENSE'
exclude 'NOTICE'
exclude 'LICENSE.txt'
exclude 'NOTICE.txt'
exclude 'META-INF/*'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/DEPENDENCIES'
it.isDirectory() ? it : zipTree(it)
}
}
}