D8 исключение при использовании Square's Wire - PullRequest
0 голосов
/ 28 июня 2018

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

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

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

Gradle's 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.

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

1 Ответ

0 голосов
/ 13 июля 2018

Причина 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 Plugin

...