realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.74k forks source link

DexException with javax.annotations since updating to Android Studio 3 + Gradle #5540

Closed jdevnano closed 6 years ago

jdevnano commented 6 years ago

I recently updated to Android 3.0, which forced an update to the project's gradle. We also had to upgrade our target SDK to 26 and support libraries. I keep encountering a DexException and unable to build.

Thanks in advance!

Actual Results

Error:Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Ljavax/annotation/CheckReturnValue;
Error:com.android.dex.DexException: Multiple dex files define Ljavax/annotation/CheckReturnValue;
Error:  at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:661)
Error:  at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:616)
Error:  at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:598)
Error:  at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171)
Error:  at com.android.dx.merge.DexMerger.merge(DexMerger.java:198)
Error:  at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:61)
Error:  at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:36)
Error:  at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
Error:  at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
Error:  at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
Error:  at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
Error:  at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Error:Execution failed for task ':app:transformDexArchiveWithDexMergerForFullDebug'.
> com.android.build.api.transform.TransformException: com.android.dex.DexException: Multiple dex files define Ljavax/annotation/CheckReturnValue;

Steps & Code to Reproduce

I used gradle to get a copy of our dependency tree. I tracked down javax.annotations library to com.google.code.findbugs:jsr305:3.0.2.

fullReleaseCompileClasspath - Resolved configuration for compilation for variant: fullRelease
+--- io.realm:realm-android-library:4.0.0
|    +--- com.google.code.findbugs:jsr305:3.0.2
|    +--- com.getkeepsafe.relinker:relinker:1.2.2
|    \--- io.realm:realm-annotations:4.0.0
+--- io.realm:realm-annotations:4.0.0
+--- project :library
+--- com.android.volley:volley:1.0.0
+--- com.android.support:appcompat-v7:26.1.0
|    +--- com.android.support:support-annotations:26.1.0
|    +--- com.android.support:support-v4:26.1.0
|    |    +--- com.android.support:support-compat:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- android.arch.lifecycle:runtime:1.0.0
|    |    |         +--- android.arch.lifecycle:common:1.0.0
|    |    |         \--- android.arch.core:common:1.0.0
|    |    +--- com.android.support:support-media-compat:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- com.android.support:support-compat:26.1.0 (*)
|    |    +--- com.android.support:support-core-utils:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- com.android.support:support-compat:26.1.0 (*)
|    |    +--- com.android.support:support-core-ui:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0
|    |    |    \--- com.android.support:support-compat:26.1.0 (*)
|    |    \--- com.android.support:support-fragment:26.1.0
|    |         +--- com.android.support:support-compat:26.1.0 (*)
|    |         +--- com.android.support:support-core-ui:26.1.0 (*)
|    |         \--- com.android.support:support-core-utils:26.1.0 (*)
|    +--- com.android.support:support-vector-drawable:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    \--- com.android.support:support-compat:26.1.0 (*)
|    \--- com.android.support:animated-vector-drawable:26.1.0
|         +--- com.android.support:support-vector-drawable:26.1.0 (*)
|         \--- com.android.support:support-core-ui:26.1.0 (*)
+--- com.android.support:cardview-v7:26.1.0
|    \--- com.android.support:support-annotations:26.1.0
+--- com.android.support:customtabs:26.1.0
|    +--- com.android.support:support-compat:26.1.0 (*)
|    \--- com.android.support:support-annotations:26.1.0
+--- com.android.support:support-v4:26.1.0 (*)
+--- com.android.support:design:26.1.0
|    +--- com.android.support:support-v4:26.1.0 (*)
|    +--- com.android.support:appcompat-v7:26.1.0 (*)
|    +--- com.android.support:recyclerview-v7:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    +--- com.android.support:support-compat:26.1.0 (*)
|    |    \--- com.android.support:support-core-ui:26.1.0 (*)
|    \--- com.android.support:transition:26.1.0
|         +--- com.android.support:support-annotations:26.1.0
|         \--- com.android.support:support-v4:26.1.0 (*)
+--- org.bouncycastle:bcprov-jdk15on:1.54
+--- net.i2p.crypto:eddsa:0.1.0
+--- org.zeromq:curve25519-java:0.1.0
+--- com.squareup.retrofit2:retrofit:2.3.0
|    \--- com.squareup.okhttp3:okhttp:3.8.0 -> 3.8.1
|         \--- com.squareup.okio:okio:1.13.0
+--- com.squareup.okhttp3:okhttp:3.8.1 (*)
+--- com.jakewharton.retrofit:retrofit1-okhttp3-client:1.1.0
|    +--- com.squareup.retrofit:retrofit:1.9.0
|    |    \--- com.google.code.gson:gson:2.3.1
|    \--- com.squareup.okhttp3:okhttp:3.2.0 -> 3.8.1 (*)
+--- com.github.andriydruk:rxdnssd:0.8.4
|    +--- io.reactivex:rxandroid:1.2.0
|    |    \--- io.reactivex:rxjava:1.1.4 -> 1.1.9
|    +--- io.reactivex:rxjava:1.1.9
|    +--- com.android.support:support-annotations:25.3.1 -> 26.1.0
|    \--- com.google.code.findbugs:annotations:2.0.1
+--- info.hoang8f:android-segmented:1.0.6
+--- me.relex:circleindicator:1.2.1
+--- com.flurry.android:analytics:7.0.0
+--- com.h6ah4i.android.widget.verticalseekbar:verticalseekbar:0.7.2
|    \--- com.android.support:appcompat-v7:25.2.0 -> 26.1.0 (*)
+--- io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.0.5
|    +--- com.android.support:appcompat-v7:23.1.1 -> 26.1.0 (*)
|    \--- com.android.support:recyclerview-v7:23.1.1 -> 26.1.0 (*)
+--- com.android.support:multidex:1.0.1
+--- com.daimajia.swipelayout:library:1.2.0
+--- com.github.clans:fab:1.6.4
+--- com.afollestad:sectioned-recyclerview:0.5.0
|    +--- com.android.support:recyclerview-v7:25.3.1 -> 26.1.0 (*)
|    \--- com.android.support:support-v4:25.3.1 -> 26.1.0 (*)
+--- com.facebook.android:facebook-android-sdk:4.16.1
|    +--- com.android.support:support-v4:23.4.0 -> 26.1.0 (*)
|    +--- com.android.support:appcompat-v7:23.4.0 -> 26.1.0 (*)
|    +--- com.android.support:cardview-v7:23.4.0 -> 26.1.0 (*)
|    +--- com.android.support:customtabs:23.4.0 -> 26.1.0 (*)
|    \--- com.parse.bolts:bolts-android:1.4.0
|         +--- com.parse.bolts:bolts-tasks:1.4.0
|         \--- com.parse.bolts:bolts-applinks:1.4.0
|              \--- com.parse.bolts:bolts-tasks:1.4.0
+--- com.android.support.constraint:constraint-layout:1.0.2
|    \--- com.android.support.constraint:constraint-layout-solver:1.0.2
\--- com.airbnb.android:lottie:2.2.5
     \--- com.android.support:appcompat-v7:26.1.0 (*)

fullReleaseCompileOnly - Compile only dependencies for 'fullRelease' sources. (n)
No dependencies

fullReleaseImplementation - Implementation only dependencies for 'fullRelease' sources. (n)
No dependencies

fullReleaseMetadataElements - Metadata elements for fullRelease (n)
No dependencies

fullReleaseProvided - Provided dependencies for 'fullRelease' sources (deprecated: use 'fullReleaseCompileOnly' instead). (n)
No dependencies

fullReleaseRuntimeClasspath - Resolved configuration for runtime for variant: fullRelease
+--- io.realm:realm-android-library:4.0.0
|    +--- com.google.code.findbugs:jsr305:3.0.2
|    +--- com.getkeepsafe.relinker:relinker:1.2.2
|    \--- io.realm:realm-annotations:4.0.0
+--- io.realm:realm-annotations:4.0.0
+--- project :library
|    \--- com.android.support:support-v4:26.1.0
|         +--- com.android.support:support-compat:26.1.0
|         |    +--- com.android.support:support-annotations:26.1.0
|         |    \--- android.arch.lifecycle:runtime:1.0.0
|         |         +--- android.arch.lifecycle:common:1.0.0
|         |         \--- android.arch.core:common:1.0.0
|         +--- com.android.support:support-media-compat:26.1.0
|         |    +--- com.android.support:support-annotations:26.1.0
|         |    \--- com.android.support:support-compat:26.1.0 (*)
|         +--- com.android.support:support-core-utils:26.1.0
|         |    +--- com.android.support:support-annotations:26.1.0
|         |    \--- com.android.support:support-compat:26.1.0 (*)
|         +--- com.android.support:support-core-ui:26.1.0
|         |    +--- com.android.support:support-annotations:26.1.0
|         |    \--- com.android.support:support-compat:26.1.0 (*)
|         \--- com.android.support:support-fragment:26.1.0
|              +--- com.android.support:support-compat:26.1.0 (*)
|              +--- com.android.support:support-core-ui:26.1.0 (*)
|              \--- com.android.support:support-core-utils:26.1.0 (*)
+--- com.android.volley:volley:1.0.0
+--- com.android.support:appcompat-v7:26.1.0
|    +--- com.android.support:support-annotations:26.1.0
|    +--- com.android.support:support-v4:26.1.0 (*)
|    +--- com.android.support:support-vector-drawable:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    \--- com.android.support:support-compat:26.1.0 (*)
|    \--- com.android.support:animated-vector-drawable:26.1.0
|         +--- com.android.support:support-vector-drawable:26.1.0 (*)
|         \--- com.android.support:support-core-ui:26.1.0 (*)
+--- com.android.support:cardview-v7:26.1.0
|    \--- com.android.support:support-annotations:26.1.0
+--- com.android.support:customtabs:26.1.0
|    +--- com.android.support:support-compat:26.1.0 (*)
|    \--- com.android.support:support-annotations:26.1.0
+--- com.android.support:support-v4:26.1.0 (*)
+--- com.android.support:design:26.1.0
|    +--- com.android.support:support-v4:26.1.0 (*)
|    +--- com.android.support:appcompat-v7:26.1.0 (*)
|    +--- com.android.support:recyclerview-v7:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0
|    |    +--- com.android.support:support-compat:26.1.0 (*)
|    |    \--- com.android.support:support-core-ui:26.1.0 (*)
|    \--- com.android.support:transition:26.1.0
|         +--- com.android.support:support-annotations:26.1.0
|         \--- com.android.support:support-v4:26.1.0 (*)
+--- org.bouncycastle:bcprov-jdk15on:1.54
+--- net.i2p.crypto:eddsa:0.1.0
+--- org.zeromq:curve25519-java:0.1.0
+--- com.squareup.retrofit2:retrofit:2.3.0
|    \--- com.squareup.okhttp3:okhttp:3.8.0 -> 3.8.1
|         \--- com.squareup.okio:okio:1.13.0
+--- com.squareup.okhttp3:okhttp:3.8.1 (*)
+--- com.jakewharton.retrofit:retrofit1-okhttp3-client:1.1.0
|    +--- com.squareup.retrofit:retrofit:1.9.0
|    |    \--- com.google.code.gson:gson:2.3.1
|    \--- com.squareup.okhttp3:okhttp:3.2.0 -> 3.8.1 (*)
+--- com.github.andriydruk:rxdnssd:0.8.4
|    +--- io.reactivex:rxandroid:1.2.0
|    |    \--- io.reactivex:rxjava:1.1.4 -> 1.1.9
|    +--- io.reactivex:rxjava:1.1.9
|    +--- com.android.support:support-annotations:25.3.1 -> 26.1.0
|    \--- com.google.code.findbugs:annotations:2.0.1
+--- info.hoang8f:android-segmented:1.0.6
+--- me.relex:circleindicator:1.2.1
+--- com.flurry.android:analytics:7.0.0
+--- com.h6ah4i.android.widget.verticalseekbar:verticalseekbar:0.7.2
|    \--- com.android.support:appcompat-v7:25.2.0 -> 26.1.0 (*)
+--- io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.0.5
|    +--- com.android.support:appcompat-v7:23.1.1 -> 26.1.0 (*)
|    \--- com.android.support:recyclerview-v7:23.1.1 -> 26.1.0 (*)
+--- com.android.support:multidex:1.0.1
+--- com.daimajia.swipelayout:library:1.2.0
+--- com.github.clans:fab:1.6.4
+--- com.afollestad:sectioned-recyclerview:0.5.0
|    +--- com.android.support:recyclerview-v7:25.3.1 -> 26.1.0 (*)
|    \--- com.android.support:support-v4:25.3.1 -> 26.1.0 (*)
+--- com.facebook.android:facebook-android-sdk:4.16.1
|    +--- com.android.support:support-v4:23.4.0 -> 26.1.0 (*)
|    +--- com.android.support:appcompat-v7:23.4.0 -> 26.1.0 (*)
|    +--- com.android.support:cardview-v7:23.4.0 -> 26.1.0 (*)
|    +--- com.android.support:customtabs:23.4.0 -> 26.1.0 (*)
|    \--- com.parse.bolts:bolts-android:1.4.0
|         +--- com.parse.bolts:bolts-tasks:1.4.0
|         \--- com.parse.bolts:bolts-applinks:1.4.0
|              \--- com.parse.bolts:bolts-tasks:1.4.0
+--- com.android.support.constraint:constraint-layout:1.0.2
|    \--- com.android.support.constraint:constraint-layout-solver:1.0.2
\--- com.airbnb.android:lottie:2.2.5
     \--- com.android.support:appcompat-v7:26.1.0 (*)

I also updated the project proguard with

#realm
-keepnames public class * extends io.realm.RealmObject
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.** { ; }
-keep class javax.** { ; }
-dontwarn javax.*
-dontwarn io.realm.**

Project level build.gradle

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
        classpath 'io.realm:realm-gradle-plugin:4.0.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        google()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Library level build.gradle

apply plugin: 'com.android.library'

dependencies {
    implementation 'com.android.support:support-v4:26.1.0'
}

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 26
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            res.srcDirs = ['res']
        }
    }
}
repositories {
    google()
}

App level build.gradle

apply plugin: 'com.android.application'
apply plugin: 'realm-android'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'

    defaultConfig {
        applicationId "me.nanoleaf.nanoleaf"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 75
        versionName "2.0.11"
        multiDexEnabled true
        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
    lintOptions {
        disable 'MissingTranslation'
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            debuggable true
            applicationIdSuffix ".debug"
        }
    }

    flavorDimensions "base"
    productFlavors {
        alpha {
            dimension "base"
            applicationIdSuffix ".alpha"
            versionNameSuffix "-alpha"
        }
        full {
            dimension "base"
        }
    }
}

dependencies {
    def withoutAnnotations = { exclude group: 'javax.annotation'
        module 'javax.annotation'}
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation project(':library')

    implementation 'com.android.volley:volley:1.0.0'
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:cardview-v7:26.1.0'
    implementation 'com.android.support:customtabs:26.1.0'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'org.bouncycastle:bcprov-jdk15on:1.54'
    implementation 'net.i2p.crypto:eddsa:0.1.0'
    implementation 'org.zeromq:curve25519-java:0.1.0'
    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.okhttp3:okhttp:3.8.1'
    implementation 'com.jakewharton.retrofit:retrofit1-okhttp3-client:1.1.0'
    implementation 'com.github.andriydruk:rxdnssd:0.8.4'
    implementation 'info.hoang8f:android-segmented:1.0.6'
    implementation 'me.relex:circleindicator:1.2.1@aar'
    implementation 'com.flurry.android:analytics:7.0.0'
    implementation 'com.h6ah4i.android.widget.verticalseekbar:verticalseekbar:0.7.2'
    implementation 'io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.0.5'
    implementation 'com.android.support:multidex:1.0.1'
    implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
    implementation 'com.github.clans:fab:1.6.4'
    implementation 'com.afollestad:sectioned-recyclerview:0.5.0'
    implementation 'com.facebook.android:facebook-android-sdk:4.16.1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.afollestad:sectioned-recyclerview:0.5.0'
    implementation 'com.airbnb.android:lottie:2.2.5'
    testImplementation 'junit:junit:4.12'
}

Version of Realm and tooling

Realm version(s): 4.0.0

Realm sync feature enabled: no

Android Studio version: 3.0

Target SDK: 26

Zhuinden commented 6 years ago

You can try

configurations.all {
    resolutionStrategy.force "com.google.code.findbugs:jsr305:3.0.2"
}
jdevnano commented 6 years ago

@Zhuinden Still the same error; I placed it in my app level gradle

apply plugin: 'com.android.application'
apply plugin: 'realm-android'

configurations.all {
    resolutionStrategy.force "com.google.code.findbugs:jsr305:3.0.2"
}
...
cmelchior commented 6 years ago

Judging from your gradle file com.google.code.findbugs:jsr305:3.0.2 is only included once, so no conflict should be possible. This leaves a couple of options:

1) It's a bug in the build system. Try to do a full clean and rebuild 2) Some of your other dependencies inlined the JSR305 dependency. This is extremely bad practice for exactly the reason you are seeing now, and should be fixed in that library. If this is not possible you can try to prevent Realm from including it. Right now we include it through our gradle plugin which makes things a little more tricky as you would manually need to duplicate the logic the plugin is doing (Add relevant dependencies + apply the Transformer).

jdevnano commented 6 years ago

I managed to figure out how to fix this issue. Thanks, @Zhuinden and @cmelchior! I used your suggestions as a starting point and found the new Gradle equivalent configs.

Instead of using

configurations.all {
    ...
}

the new gradle in AS 3.0 requires you to use their Variant API. For more, see here.

What worked for me:

apply plugin: 'com.android.application'
apply plugin: 'realm-android'

android {
    applicationVariants.all { variant ->
        variant.getRuntimeConfiguration().exclude group: 'com.google.code.findbugs', module: 'jsr305'
    }
...