【问题标题】:D8 exception when using Square's Wire使用 Square 的 Wire 时出现 D8 异常
【发布时间】:2018-06-28 01:34:59
【问题描述】:

在 Android 项目中添加 Square 的 Wire 库以支持 Protobuf 后,我在编译期间收到以下 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 个模块 ABCA 取决于 BCBC 都托管在内部 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 时,一切都很美好,但是当A 依赖于BC 时,D8 会感到难过。

那么你如何依赖多个传递依赖 Wire 的模块呢?

【问题讨论】:

    标签: android protocol-buffers maven-publish android-d8 square-wire


    【解决方案1】:

    D8伤心的原因

    当您运行 Wire 代码生成器时,它会在您的项目中创建一些 Java 源文件,所有其他 Wire 代码生成的代码都依赖这些源文件。 com.google.protobuf.DescriptorProto就是这样一个文件。因此,当您依赖两个使用 Wire 的模块时,您将拥有两个模块,它们都包含具有相同名称和包的 Java 源文件,并最终得到重复的 .class 文件。这些 .class 文件是您的库模块打包输出的一部分(不是传递依赖项),因此再多的 gradle exclude 也无济于事(除非您知道一些我不知道的 Gradle 恶作剧?...)。

    可能的解决方案

    在您的库模块中设置打包选项以包含 java 源代码,以便您仍然可以编译,但在打包 aar 时排除 .class 文件。我试过这个,但无法使打包选项实际上排除 .class 文件。即使它有效,我也不喜欢这种方法,所以我放弃了它。

    (没试过,可能有用)将 Wire 生成的 com.google.protobuf 源文件捆绑到您自己的单独库中,以便它们成为传递依赖项。您可能希望在运行 Wire 后编写一个处理此过程的 gradle 任务,以免每次都手动移动这些文件。在您的应用程序中包含该库的单个副本并使用gradle exclude 忽略传递。

    最终感觉时间同步太多了,我选择使用Protobuf Gradle Plugin

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 2015-02-05
      • 2014-08-06
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多