D8 исключение при использовании Square's Wire

После добавления библиотеки Square Wire для поддержки Protobuf в проект Android, я получаю следующее исключение D8 во время компиляции:

D8: тип программы уже представлен: com.google.protobuf.DescriptorProto$ExtensionRange$ProtoAdapter_ExtensionRange

зависимость от провода: implementation 'com.squareup.wire:wire-runtime:2.2.0'

Gradle-х dependencyInsight выявил еще одну зависимость в моем проекте, которая переходила в com.google.protobuf.nano:protobuf-javanano:3.1.0, Поэтому я добавил исключение с помощью:

implementation ('com.google.vr:sdk-base:1.100.0'){
  exclude group: 'com.google.protobuf.nano'
}

но это не решило проблему.

Что делает D8 грустным, и как я могу сделать его снова счастливым?

Обновить

Проблемная настройка: есть 3 модуля A, B, C, A зависит от B а также C, B а также C оба размещены на внутреннем сервере maven, каждый из которых зависит от wire-runtime со следующей записью POM:

<dependency>
  <groupId>com.squareup.wire</groupId>
  <artifactId>wire-runtime</artifactId>
  <version>2.3.0-RC1</version>
  <scope>compile</scope>
</dependency>

Я пробовал Wire версии 2.2 и 2.3.0. Все персик когда A зависит только от B или только C, но D8 грустит, когда A зависит от обоих B а также C,

Итак, как вы зависите от нескольких модулей, которые транзитивно зависят от провода?

1 ответ

Причина D8 грустна

Когда вы запускаете Wire code gen, он создает несколько исходных файлов Java в вашем проекте, от которых зависит весь остальной код, созданный с помощью Wire-кода. com.google.protobuf.DescriptorProtoэто один такой файл. Поэтому, когда вы зависите от двух модулей, которые используют Wire, у вас есть два модуля, каждый из которых содержит исходный файл Java с тем же именем и пакетом, и в итоге получаются дубликаты.class-файлов. Эти файлы.class являются частью упакованного вывода ваших библиотечных модулей (не транзитивная зависимость), поэтому никакое количество gradle exclude поможет (если вы не знаете некоторые махинации Gradle, что я не знаю?...).

Возможные решения

Настройте параметры упаковки в модуле библиотеки, включив в нее исходные коды java, чтобы вы могли по-прежнему компилировать, но исключать файлы.class при упаковке aar. Я попробовал это, но не смог сделать так, чтобы параметры упаковки действительно исключали файлы.class. Я не был в восторге от такого подхода, даже если он сработал, поэтому я отказался от него.

(не пытался, может сработать) com.google.protobuf исходные файлы, которые Wire создает в вашу собственную отдельную библиотеку, чтобы они стали переходной зависимостью. Возможно, вы захотите написать задачу gradle, которая обрабатывает этот процесс после запуска Wire, чтобы не перемещать эти файлы каждый раз вручную. Включите одну копию указанной библиотеки в ваше приложение и используйте gradle exclude игнорировать переходные процессы.

В конечном итоге это выглядело как слишком большая временная синхронизация, и я решил использовать плагин Protobuf Gradle

Другие вопросы по тегам