Ошибка градиента нескольких файлов dex в Android Studio

Я получаю эту ошибку, когда я запускаю-> приложение для приложения Android в Android Studio

UNEXPECTED TOP-LEVEL EXCEPTION:
    com.android.dex.DexException: Multiple dex files define Lcom/google/common/annotations/Beta;
...

А вот вывод gradlew -q :app:dependencies

+--- project :shared
+--- com.google.api-client:google-api-client:1.19.0
|    +--- com.google.oauth-client:google-oauth-client:1.19.0
|    |    +--- com.google.http-client:google-http-client:1.19.0
|    |    |    +--- com.google.code.findbugs:jsr305:1.3.9
|    |    |    \--- org.apache.httpcomponents:httpclient:4.0.1
|    |    |         +--- org.apache.httpcomponents:httpcore:4.0.1
|    |    |         +--- commons-logging:commons-logging:1.1.1
|    |    |         \--- commons-codec:commons-codec:1.3
|    |    \--- com.google.code.findbugs:jsr305:1.3.9
|    +--- com.google.http-client:google-http-client-jackson2:1.19.0
|    |    +--- com.google.http-client:google-http-client:1.19.0 (*)
|    |    \--- com.fasterxml.jackson.core:jackson-core:2.1.3
|    \--- com.google.guava:guava-jdk5:13.0
+--- com.google.http-client:google-http-client-gson:1.19.0
|    \--- com.google.code.gson:gson:2.1
+--- com.google.api-client:google-api-client-android:1.19.0
|    +--- com.google.api-client:google-api-client:1.19.0 (*)
|    \--- com.google.http-client:google-http-client-android:1.19.0
|         \--- com.google.http-client:google-http-client:1.19.0 (*)
+--- com.google.http-client:google-http-client-android:1.19.0 (*)
+--- com.google.guava:guava:14.0.+ -> 14.0.1
+--- project :backend-appengine
|    \--- com.google.api-client:google-api-client-android:1.19.0 (*)
+--- com.android.support:appcompat-v7:20.0.0
|    \--- com.android.support:support-v4:20.0.0
|         \--- com.android.support:support-annotations:20.0.0
+--- com.google.android.gms:play-services:5.0.89
\--- com.google.maps.android:android-maps-utils:0.3.+ -> 0.3.1

Вот блок зависимостей от build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':shared')
    // Add the Google API client library.
    compile(group: 'com.google.api-client', name: 'google-api-client', version: '1.19.0') {
        // Exclude artifacts that the Android SDK/Runtime provides.
        exclude(group: 'com.google.guava')     //-- !!! this does not seem to work !!!
        exclude(group: 'xpp3', module: 'xpp3')
        exclude(group: 'org.apache.httpcomponents', module: 'httpclient')
        exclude(group: 'junit', module: 'junit')
        exclude(group: 'com.google.android', module: 'android')
        exclude(group: 'com.google.http-client', module: 'google-http-client')
    }

    compile('com.google.http-client:google-http-client-gson:1.19.0') {
        exclude module: 'httpclient'
        exclude(group: 'com.google.http-client', module: 'google-http-client')
    }

    compile(group: 'com.google.api-client', name: 'google-api-client-android', version: '1.19.0') {
        exclude(group: 'com.google.android.gms', module: 'play-services')
        exclude group: 'com.google.guava', module: 'guava-jdk5'
    }

   compile(group: 'com.google.http-client', name: 'google-http-client-android', version: '1.19.0') {
        exclude(group: 'com.google.android', module: 'android')
    }

    // This is used by the Google HTTP client library.
    compile(group: 'com.google.guava', name: 'guava', version: '14.0.+')

    //-- endpoints
    dependencies {
        compile project(path: ':backend-appengine', configuration: 'android-endpoints')
    }

    compile 'com.android.support:appcompat-v7:20.0.0'
    compile ('com.google.android.gms:play-services:5.0.89') {
        exclude(group: 'com.android.support', module: 'support-v4')
    }
    compile ('com.google.maps.android:android-maps-utils:0.3.+') {
        exclude(group: 'com.google.android.gms', module: 'play-services')
    }   
}

person aez    schedule 22.09.2014    source источник


Ответы (4)


Пакет com.google.common.annotations кажется частью Guava. Я вижу его в зависимостях дважды в немного разных вариациях: один раз как часть Google API Client, один раз как вашу собственную зависимость:

+--- com.google.api-client:google-api-client:1.19.0
|    \--- com.google.guava:guava-jdk5:13.0

а также

+--- com.google.guava:guava:14.0.+ -> 14.0.1

Таким образом, причина этой ошибки заключается в том, что у вас есть одни и те же классы, определенные в нескольких файлах dex (в разных вариантах библиотеки Guava), которые включены в другие ваши зависимости. Вам нужно будет найти способ исключить эти повторяющиеся зависимости или, возможно, просто убедиться, что вы используете одну и ту же версию во всех зависимостях.

Вы можете попробовать исключить модуль guava из одной из зависимостей. Итак, если у вас определен клиентский модуль API, добавьте правило исключения для модуля guava:

compile ('com.google.api-client:google-api-client:1.19.0') {
    exclude group: 'com.google.guava', module: 'guava-jdk5'
}

Я не могу гарантировать, что это не вызовет проблем с клиентской библиотекой Google API (поскольку это две разные версии Guava), но попробовать стоит.

РЕДАКТИРОВАТЬ: из ваших зависимостей попробуйте изменить это:

compile(group: 'com.google.api-client', name: 'google-api-client', version: '1.19.0') {
    // Exclude artifacts that the Android SDK/Runtime provides.
    exclude(group: 'com.google.guava')     //-- !!! this does not seem to work !!!

to:

compile(group: 'com.google.api-client', name: 'google-api-client', version: '1.19.0') {
    exclude(group: 'com.google.guava', module: 'guava-jdk5')

Библиотека google-api-client-android на самом деле не содержит Guava - я не знал, что у вас есть две зависимости с одинаковыми именами.

person Kevin Coppock    schedule 22.09.2014
comment
Спасибо, kcoppock. Я думаю, вы должны быть правы, но как бы я ни пытался, я не могу исключить модуль guava из компиляции com.google.api-client. Почему это так? Я использую: compile(group: 'com.google.api-client', name: 'google-api-client', version: '1.19.0') { exclude(group: 'com.google.guava')} и любая другая исключающая возможность, которую я могу придумать, но она никогда не исключается - person aez; 23.09.2014
comment
Однако, kcoppock, я знаю, что вы правы, потому что я закомментировал вторую компиляцию гуавы (14.0) и могу собрать. Но все же я хочу иметь возможность исключить первый модуль гуавы, но класс, похоже, не позволяет этого. Есть идеи, почему? - person aez; 23.09.2014
comment
Вы уверены, что изменили свою зависимость точно, как показано выше? Я только что попробовал это сам, и без моей строки исключения он не собирается так же, как ваш. С линией исключения это удается. - person Kevin Coppock; 23.09.2014
comment
Насколько я могу судить, вы помещаете исключение с модулем google-api-client-ANDROID, но модуль guava, который мы пытаемся исключить, находится с более ранним модулем google-api-client вверху. Поэтому, когда я ставлю исключение точно так же, как у вас, с именно тем компилятором, который вы показываете, он ничего не делает, потому что с этим конкретным компилятором нет гуавы. И действительно, снова собрать не получается. - person aez; 23.09.2014
comment
Можете ли вы опубликовать весь блок зависимостей? - person Kevin Coppock; 23.09.2014
comment
Смотрите мое обновление. Я неправильно прочитал ваши зависимости (поскольку у вас есть две похожие библиотеки api-client и api-client-android). Библиотека Android не содержит зависимости от Guava — это стандартная библиотека API-клиента. - person Kevin Coppock; 23.09.2014
comment
Спасибо, но последнее исключение тоже не работает. Это просто не исключает модуль гуавы. Повторный запуск зависимостей gradle -q показывает модуль guava даже с последним исключением. - person aez; 23.09.2014
comment
В любом случае, вы достаточно усердно работали над этим вопросом. Если вы отредактируете его, просто отметив, что у меня было две версии одного и того же модуля и что одну из них нужно исключить, я приму ваш ответ. Затем я отвечу и опубликую еще один вопрос о проблеме исключения. Спасибо - person aez; 23.09.2014
comment
Обновлено. :) Извините, я не смог найти для вас полное решение, но, возможно, оно поможет вам встать на правильный путь. - person Kevin Coppock; 23.09.2014
comment
если вы считаете, что вопрос стоит обсуждения на форуме, проголосуйте за него. - person aez; 23.09.2014
comment
см. мое решение раньше, я считаю, что это более правильный подход - person Creos; 23.02.2016

Для тех, кто использует Google Cloud Endpoints в приложении Android:

compile(project(path: ':backend', configuration: 'android-endpoints')) {
    exclude(module: 'guava-jdk5')
}

Где backend — это имя вашего модуля с приложением AppEngine.

В любом другом случае просто найдите guava-jdk5 транзитивную зависимость и исключите ее.

person tomrozb    schedule 02.12.2014
comment
Большое спасибо, я искал это целую вечность. - person danwms; 09.01.2015
comment
Это спасло меня. Спасибо - person Matteo Di Napoli; 04.05.2016

Вот правильное решение, сработало для меня. Исключение модуля зависимостей guava-jdk5 из каждого отдельного импорта контрпродуктивно (для меня это не сработало, потому что у меня были некоторые внутренние зависимости, исходящие из моего бэкэнда, от которых зависит мое приложение, и это обнажает реальную проблему с этим подходом).

Следующее решило проблему и является рекомендуемым подходом:

configurations {
    all*.exclude group: 'com.google.guava', module: 'guava-jdk5'
}

Источник: https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html

person Creos    schedule 21.02.2016
comment
Спасибо за это, сэкономил мне пару часов. - person Sergio Serra; 23.03.2017
comment
наверное лучшее решение - person Rahul Chaube; 06.04.2017
comment
Спасибо, если это было полезно, пожалуйста, проголосуйте, я думаю, что это правильное решение и лучше, чем принятый ответ. - person Creos; 06.04.2017

Кажется, вы не можете использовать и guava, и guava-jdk5 в одном проекте. Guava-jdk5 все еще поддерживается, поэтому рассмотрите возможность изменения ссылки на guava вашего проекта на guava-jdk5:

compile 'com.google.guava:guava-jdk5:17.0'
person PacificSky    schedule 01.11.2014
comment
У меня работал только этот раствор. Исключение guava-jdk5 из библиотеки конечных точек, как было предложено выше, казалось более привлекательным решением, но оно не сработало. - person Tom; 28.04.2015