Duplicate classes in kotlin-runtime and com.intellij:annotations

When I use Kotlin and 'com.intellij:annotations' is being referenced by the project, the build fails with following output:

UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexException: Multiple dex files define Lorg/jetbrains/annotations/NotNull;   at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:596)   at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:554)   at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:535)   at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171)   at com.android.dx.merge.DexMerger.merge(DexMerger.java:189)   at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:502)   at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334)   at com.android.dx.command.dexer.Main.run(Main.java:277)   at com.android.dx.command.dexer.Main.main(Main.java:245)   at com.android.dx.command.Main.main(Main.java:106)

After some research I found that org.jetbrains.annotations.{NotNull, Nullable} classes are present in both kotlin-runtime and com.intellij:annotations.

It would be easy if I remove com.intellij:annotations from the project dependency but this one is being referenced by an external library, not the project itself.

Is there any way to address this issue?

You can exclude a transitive dependency from your Gradle dependencies so it will not be processed by the dex utility.

"useful.framework:main:1.0") {
        exclude module: 'unwanted-library'
    }
}

Please see Exclude Transitive Dependencies for more information.

While exclusion is “nice”, we can do better. I’ve added the following snippets to my build file to handle it better (Other annotations in the annotation package are used as well).

Basically, the excluded annotations library is replaced by a file dependency on a jar file that automatically has the offending classes stripped out.

configurations {
    cleanedAnnotations

    compile.exclude group: 'org.jetbrains' , module:'annotations'
}

dependencies {
    compile files("${buildDir}/libs/annotations-cleaned.jar") { builtBy 'cleanAnnotationsJar' }
    cleanedAnnotations 'org.jetbrains:annotations:13.0'

task cleanAnnotationsJar(type:Jar) {
    configurations.cleanedAnnotations.each { f ->
        from zipTree(f)
    }
    archiveName = "annotations-cleaned.jar"
    exclude 'org/jetbrains/annotations/NotNull.class'
    exclude 'org/jetbrains/annotations/Nullable.class'
}

I tried out this (with ‘org/intellij/lang/annotations/Flow.class’, which was causing trouble), but when I look for ‘Flow’ after build it still shows the .class it twice, in my dependency as well es in annotations-cleaned.jar. Why is this…?

I also tried with ‘org/jetbrains/annotations/Flow.class’, same result…

I don’t understand can you please explain me thanks!