This Gradle plugin checks whether different artifacts in a configuration provide the same classes. Since this leads to rather nasty bugs, you probably want to find these problems beforehand. A typical cause of such issues are artifacts that changed their maven group id but kept there packages like 'c3p0:c3p0' that has been renamed to 'com.mchange:c3p0'.
You can either use the new plugin mechanism introduced with Gradle 2.1
plugins {
id 'net.idlestate.gradle-duplicate-classes-check' version '1.2.0'
}
or the 'classic' way
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'gradle.plugin.net.idlestate:gradle-duplicate-classes-check:1.2.0'
}
}
apply plugin: 'net.idlestate.gradle-duplicate-classes-check'
to apply the plugin to your project.
The check is performed by the task checkForDuplicateClasses
that has been added as dependency to the task check
.
By default, this task fails the build if any duplicate files are found in the dependency JAR’s. You can change that and just get a report when you set
ignoreFailures = true
plugins {
id 'net.idlestate.gradle-duplicate-classes-check' version '1.2.0'
}
checkForDuplicateClasses {
ignoreFailures = true
}
By default, all dependencies are included in the comparison and the following files and directory content is excluded:
-
directory names
-
files in
META-INF
, and it’s subdirectories -
files in
OSGI-INF
, and it’s subdirectories -
module-info.class
-
*.html
-
*.htm
-
*.txt
-
*.doc
-
README.*
-
LICENSE
-
NOTICE
To add more filters to the list you can use excludes()
. It takes one or more regular expressions as parameter that is used to match against file name.
You can also specify explicitly which files to be compared with includes()
. It also accepts one or more regular expressions as parameter.
excludes
take precedence when matching file names.
You can also use includes
and excludes
to filter for specific JAR files.
You can also use excludeModules
or excludeModule
to exclude a module based on its identifier. The former method expects a ModuleIdentifier
and the latter is a convenience method that allows the module identifier to be specified as a string.
import org.gradle.api.internal.artifacts.DefaultModuleIdentifier
plugins {
id 'net.idlestate.gradle-duplicate-classes-check' version '1.2.0'
}
checkForDuplicateClasses {
// Exclude all jar files that has javax in their name
excludes('(javax)*.(.jar)')
// This will exclude *.rtf files from comparison
excludes('.*(.rtf)^')
// Will check for presence only for class files that has OnlyThese in their name
includes('(OnlyThese).*(.class)^')
// Exclude modules with the different variants
excludeModules([DefaultModuleIdentifier.newId('group', 'name')])
excludeModule('group:name')
}
When you use this plugin in multi-module projects, and you have enabled parallel builds it is recommended to add dependsOn
to checkForDuplicateClasses
task. This will guarantee that task will execute after all dependencies have been generated.
plugins {
id 'net.idlestate.gradle-duplicate-classes-check' version '1.2.0'
}
checkForDuplicateClasses {
dependsOn 'jar'
}