Android Studio 3.0 へ移行するための動作確認を行って際に結構ハマったので情報共有します。
エラー内容
- Android Studio 2.3から3.0へのマイグレーションポイント - Qiita
- Migrate to Android Plugin for Gradle 3.0.0 - Android Devlper
上記などを参考に移行の作業を行い、最後に実機での確認を行った際に下記エラーが発生。
Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
14:57:28.124 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
> com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex
原因
Gradleに登録しているライブラリが依存しているライブラリ(日本語難しいですね)が、重複していたため
例えば、AというライブラリはBライブラリを使用していて、CライブラリもBライブラリを使用していた、など。
対処法
まずは、コンパイルオプションに--stacktrace
を付けてビルドし、何が重複したのかを特定します。
コンパイルオプションは、Preference > Build, Execution, Development > Compiler > Command-line Options
で帰れます。今回の問題のみならず、何かコンパイルでエラーが発生したときはこれを使えばだいたい何が悪いのかわかります。
今回こちらの環境では下記が問題になっていました。
Caused by: com.android.dex.DexException: Multiple dex files define Lorg/objectweb/asm/AnnotationWriter;
org.objectweb
とかasm
というのが問題のようです。
続いて、どのライブラリが上記使っているのかを探します。
コマンドラインで下記コマンドを入力します。Windowsの人は適宜読み替えてください。
./gradlew app:dependencies
すると、下記のように使用しているライブラリの依存ツリーが表示されるので、どのライブラリが使っているのかを特定します。
debugRuntimeClasspath - Resolved configuration for runtime for variant: debug
+--- org.jacoco:org.jacoco.agent:0.7.4.201502262128
+--- com.android.support:design:26.0.2
| +--- com.android.support:support-v4:26.0.2
| | +--- com.android.support:support-compat:26.0.2
| | | \--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | +--- com.android.support:support-media-compat:26.0.2
| | | +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | | \--- com.android.support:support-compat:26.0.2 (*)
| | +--- com.android.support:support-core-utils:26.0.2
| | | +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | | \--- com.android.support:support-compat:26.0.2 (*)
| | +--- com.android.support:support-core-ui:26.0.2
| | | +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | | \--- com.android.support:support-compat:26.0.2 (*)
| | \--- com.android.support:support-fragment:26.0.2
| | +--- com.android.support:support-compat:26.0.2 (*)
| | +--- com.android.support:support-core-ui:26.0.2 (*)
| | \--- com.android.support:support-core-utils:26.0.2 (*)
| +--- com.android.support:appcompat-v7:26.0.2
| | +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | +--- com.android.support:support-v4:26.0.2 (*)
| | +--- com.android.support:support-vector-drawable:26.0.2
| | | +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | | \--- com.android.support:support-compat:26.0.2 (*)
| | \--- com.android.support:animated-vector-drawable:26.0.2
| | +--- com.android.support:support-vector-drawable:26.0.2 (*)
| | \--- com.android.support:support-core-ui:26.0.2 (*)
| +--- com.android.support:recyclerview-v7:26.0.2
| | +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| | +--- com.android.support:support-compat:26.0.2 (*)
| | \--- com.android.support:support-core-ui:26.0.2 (*)
| \--- com.android.support:transition:26.0.2
| +--- com.android.support:support-annotations:26.0.2 -> 26.1.0
| \--- com.android.support:support-v4:26.0.2 (*)
+--- com.android.support:appcompat-v7:26.0.2 (*)
+--- com.squareup.retrofit2:retrofit:2.3.0
| \--- com.squareup.okhttp3:okhttp:3.8.0
| \--- com.squareup.okio:okio:1.13.0
+--- com.squareup.retrofit2:retrofit-mock:2.3.0
| \--- com.squareup.retrofit2:retrofit:2.3.0 (*)
+--- com.squareup.retrofit2:converter-gson:2.3.0
| +--- com.squareup.retrofit2:retrofit:2.3.0 (*)
| \--- com.google.code.gson:gson:2.7 -> 2.8.2
+--- com.squareup.retrofit2:adapter-rxjava:2.3.0
| +--- com.squareup.retrofit2:retrofit:2.3.0 (*)
| \--- io.reactivex:rxjava:1.3.0
+--- com.squareup.okhttp3:logging-interceptor:3.8.0
| \--- com.squareup.okhttp3:okhttp:3.8.0 (*)
+--- io.reactivex:rxandroid:1.2.1
| \--- io.reactivex:rxjava:1.1.6 -> 1.3.0
+--- io.reactivex:rxjava:1.1.6 -> 1.3.0
+--- com.trello:rxlifecycle:1.0
| +--- io.reactivex:rxjava:1.2.1 -> 1.3.0
| \--- com.google.code.findbugs:jsr305:3.0.1
+--- com.trello:rxlifecycle-android:1.0
| +--- com.trello:rxlifecycle:1.0 (*)
| \--- com.jakewharton.rxbinding:rxbinding:0.4.0
| +--- io.reactivex:rxandroid:1.1.0 -> 1.2.1 (*)
| +--- io.reactivex:rxjava:1.1.0 -> 1.3.0
| \--- com.android.support:support-annotations:23.1.0 -> 26.1.0
+--- com.trello:rxlifecycle-components:1.0
| +--- com.trello:rxlifecycle-android:1.0 (*)
| +--- io.reactivex:rxjava:1.2.1 -> 1.3.0
| \--- com.android.support:appcompat-v7:25.0.0 -> 26.0.2 (*)
+--- com.google.guava:guava:20.0
+--- com.google.code.gson:gson:2.8.2
+--- com.jayway.jsonpath:json-path:2.0.0
| +--- org.slf4j:slf4j-api:1.7.10
| \--- net.minidev:json-smart:2.1.1
| \--- net.minidev:asm:1.0.2
| \--- asm:asm:3.3.1
+--- me.dm7.barcodescanner:zxing:1.9.8
| +--- me.dm7.barcodescanner:core:1.9.8
| | \--- com.android.support:support-v4:25.3.1 -> 26.0.2 (*)
| \--- com.google.zxing:core:3.3.0
+--- com.twilio:video-android:1.3.4
| +--- com.android.support:support-annotations:26.1.0
| \--- com.getkeepsafe.relinker:relinker:1.2.2
+--- com.wang.avi:library:2.1.3
+--- uk.co.chrisjenx:calligraphy:2.3.0
| \--- com.android.support:appcompat-v7:25.3.1 -> 26.0.2 (*)
+--- com.jakewharton:butterknife:8.8.1
| +--- com.jakewharton:butterknife-annotations:8.8.1
| | \--- com.android.support:support-annotations:25.3.0 -> 26.1.0
| +--- com.android.support:support-annotations:25.3.0 -> 26.1.0
| \--- com.android.support:support-compat:25.3.0 -> 26.0.2 (*)
+--- com.daimajia.easing:library:2.1
| \--- com.android.support:appcompat-v7:25.1.1 -> 26.0.2 (*)
+--- com.daimajia.androidanimations:library:2.3
+--- com.microsoft.azure.mobile:mobile-center-analytics:0.12.0
| \--- com.microsoft.azure.mobile:mobile-center:0.12.0
+--- com.microsoft.azure.mobile:mobile-center-crashes:0.12.0
| \--- com.microsoft.azure.mobile:mobile-center:0.12.0
\--- net.danlew:android.joda:2.9.9
\--- joda-time:joda-time:2.9.9
json-path
が、net.minidev:asm:1.0.2
を使っているのがわかりました。
そこで、このライブラリに対してexcludeコマンドをつかって除外してやります。
compile('com.jayway.jsonpath:json-path:2.0.0') {
exclude group: 'net.minidev', module: 'asm'
}
これで終わりです。
あとは、念のために、プロジェクト直下の./gradle
,build
とapp/build
を削除して、Clean
-> Rebuild
します。
私はこの方法で解消できました。
その他のアプローチ
いろいろ調べていく中で他の方法でも、上手く行った人がいるようなのでご紹介します。試してみると良いかもしれません。
- ただ単に、
Clean
->Rebuild
-
app/build.gradle
にmultiDexEnabled true
を追加 -
compileSdkVersion
,compileSdkVersion
,supportLibVersion
を全て同じバージョンに揃える - プロジェクト直下の
./gradle
,build
とapp/build
を削除して、Clean
->Rebuild
- Google Play Services を最新バージョンにアップデート
-
app/build.gradle
にdexOption
にjumboMode true
を追加する - complie を implementationに、 testCompiple を testImplementationに、 testImplementation を androidTestImplementationに置き換える