Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Utility Gradle task to find where duplicate classes come from (for Gradle 4.1+)
// H/t to https://github.com/ethankhall/scripts/blob/master/gradle/find-file.gradle for the idea;
// this re-written version actually works in modern Gradle and Android Gradle plugins.
task findInDependencies {
doLast {
println()
def resolvableConfigs = project.getConfigurations()
.stream()
.filter { it.isCanBeResolved() }
resolvableConfigs.each { config ->
config.resolve()
.stream()
.filter {
//noinspection GroovyPointlessBoolean
zipTree(it)
.filter { it.name.startsWith 'Nonnegative' } // TODO replace `Nonnegative` with what you are looking for
.each { println " Match: $it.path" }
.toList()
.isEmpty() == false
}
.each {
println "Found in `$config.name: $it.name`\n"
}
}
}
}
@rock3r

This comment has been minimized.

Copy link
Owner Author

@rock3r rock3r commented Jul 14, 2017

This is useful for when your build breaks because of errors such as com.android.dex.DexException: Multiple dex files define L...;.

Common culprits are Findbugs 3.0.1 and its annotations that include the JSR305 annotations, such as javax/annotation/Nonnegative etc. In these cases you need to manually exclude those transitive dependencies from the all those that declare them, and re-declare them explicitly yourself. The dependencies task can be very useful to determine what top-level dependencies transitively include them.

@saket

This comment has been minimized.

Copy link

@saket saket commented Mar 29, 2018

LeftShift has been deprecated and will no longer work with Gradle v5. This can be fixed by using this instead:

task findInDependencies {
  doLast {
    println()

    def resolvableConfigs = project.getConfigurations()
        .stream()
        .filter { it.isCanBeResolved() }

    resolvableConfigs.each { config ->
      config.resolve()
          .stream()
          .filter {
        //noinspection GroovyPointlessBoolean
        zipTree(it)
            .filter { it.name.startsWith 'Nonnegative' }        // TODO replace `Nonnegative` with what you are looking for
            .each { println "    Match: $it.path" }
            .toList()
            .isEmpty() == false
      }
      .each {
        println "Found in `$config.name: $it.name`\n"
      }
    }
  }
}
@rock3r

This comment has been minimized.

Copy link
Owner Author

@rock3r rock3r commented Aug 7, 2018

Thanks, I have incorporated it in the main gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.