The ContextI recently hit a wall while upgrading a legacy Android project to support the latest version of a popular third-party SDK. Everything looked fine in the code editor, but the moment I triggered a build, the Gradle execution failed with a frustrating 'Duplicate class' error. This specific issue started popping up frequently after Kotlin 1.8.0 was released because JetBrains decided to merge the functionalities of kotlin-stdlib-jdk7 and kotlin-stdlib-jdk8 into the main kotlin-stdlib.
When your project dependencies are a mix of older libraries (pointing to the split artifacts) and newer libraries (pointing to the unified artifact), Gradle sees the same classes in two different places and stops the build to prevent runtime crashes.
The Error MessageThe build output usually looks like this:
Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-jdk8 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21) and kotlin-stdlib (org.jetbrains.kotlin:kotlin-stdlib:1.8.10)
Duplicate class kotlin.jvm.jdk8.JvmRepeatableKt found in modules kotlin-stdlib-jdk8 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21) and kotlin-stdlib (org.jetbrains.kotlin:kotlin-stdlib:1.8.10)
...
Debugging the Dependency GraphBefore jumping into a fix, I needed to see which library was still pulling in the old kotlin-stdlib-jdk8. I used the Gradle dependencies command in the Android Studio terminal:
./gradlew :app:dependencies
I searched the output (Ctrl+F) for "kotlin-stdlib-jdk8". I found that an old version of a networking library was transitively bringing in Kotlin 1.6.21. Meanwhile, my project was set to use Kotlin 1.8.10. Because 1.8.10 already includes those classes, the conflict was inevitable.
The SolutionThere are a few ways to handle this, but the most robust method I've found involves forcing Gradle to resolve all Kotlin stdlib modules to the same version or excluding the redundant ones entirely.
Option 1: Using Dependency Constraints (Recommended)This is the cleanest approach. It tells Gradle that if it sees any of these specific modules, it must use a specific version, effectively overriding the transitive dependencies from older libraries. Add this to your app/build.gradle (or your root build.gradle if you have multiple modules):
dependencies {
constraints {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
because("kotlin-stdlib-jdk7 is now part of kotlin-stdlib")
}
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
because("kotlin-stdlib-jdk8 is now part of kotlin-stdlib")
}
}
}
Option 2: Excluding Modules GloballyIf the constraints don't work for some reason, you can forcefully exclude the old modules from the entire build configuration. Add this block to your project-level build.gradle file:
subprojects {
project.configurations.all {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'org.jetbrains.kotlin') {
if (details.requested.name == 'kotlin-stdlib-jdk7' || details.requested.name == 'kotlin-stdlib-jdk8') {
details.useTarget "org.jetbrains.kotlin:kotlin-stdlib:${details.requested.version}"
}
}
}
}
}
Option 3: Updating the Kotlin VersionSometimes, simply ensuring your project-level Kotlin version is consistent across all modules fixes the issue. In your build.gradle (Project level):
plugins {
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
}
And ensure you aren't manually defining implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" in your app/build.gradle. Just use implementation "org.jetbrains.kotlin:kotlin-stdlib" or let the Kotlin Gradle plugin handle it automatically.
Verification StepsAfter applying the changes, I followed these steps to make sure the fix was solid:
- Clean Project: Go to
Build > Clean Project.- Invalidate Caches: Go toFile > Invalidate Caches... > Invalidate and Restart. This ensures no old build artifacts are lingering.- Run Build: Run./gradlew assembleDebugfrom the terminal.- Check Dependencies again: Run./gradlew :app:dependencies | grep kotlin-stdlibto confirm that only one version is being used.## Lessons LearnedThe transition from Kotlin 1.7 to 1.8 changed how the standard library is packaged, which is the root cause of 90% of these 'Duplicate class' errors in modern Android development. Whenever you see a conflict between ajdk7/jdk8artifact and a basestdlib, it's almost always a version mismatch. Usingconstraintsis my go-to solution now because it documents why the override exists without hacking the dependency tree too aggressively.

