Skip to content
Latchkey

Gradle/D8 "Duplicate class ... found in modules" - Fix in CI

The D8 dexer (or the JVM classpath) found the same fully-qualified class in two different artifacts on the runtime classpath. The classic case is a library split across -jdk7/-jdk8 jars, or two annotation jars, both providing the same classes. D8 fails rather than guess which to keep.

What this error means

The build fails (often at mergeDexDebug/checkDebugDuplicateClasses) with Duplicate class <fqcn> found in modules <A> (group:name:ver) and <B> (group:name:ver), listing each colliding class.

gradle output
> Task :app:checkDebugDuplicateClasses FAILED
Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules
kotlin-stdlib-1.9.0 (org.jetbrains.kotlin:kotlin-stdlib:1.9.0) and
kotlin-stdlib-jdk8-1.6.0 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0)

Common causes

Two artifacts ship the same class

A library that merged its -jdk7/-jdk8 companion into the main artifact, plus an older transitive dependency that still pulls the separate jar, both define the same classes.

Mismatched versions of a split library

Different transitive versions of a library family (e.g. kotlin-stdlib vs kotlin-stdlib-jdk8) overlap in the classes they provide.

How to fix it

Exclude the redundant module

Drop the obsolete split artifact so only one provides the classes.

build.gradle.kts
dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0")
    // ensure nothing drags in the old split jar:
    configurations.all {
        exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk8")
    }
}

Align versions with a platform/BOM

Force one consistent version of the library family so the splits no longer overlap.

build.gradle.kts
dependencies {
    implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.0"))
}

How to prevent it

  • Align versions of split library families via a BOM/platform.
  • Exclude obsolete -jdk7/-jdk8 (or equivalent) split artifacts after upgrades.
  • Inspect runtimeClasspath after dependency bumps to catch overlapping classes.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →