找不到引用的方法'java.lang.Object InjectMembers(dagger.MembersInjector,java.lang.Object)

问题描述 投票:0回答:1

最近我将 Dagger 2.13 升级到 2.19,在这个警告的 Proguard 阶段出现以下编译错误。

Warning: com.mypackage.MyClass_Factory: can't find referenced method 'java.lang.Object injectMembers(dagger.MembersInjector,java.lang.Object)' in program class dagger.internal.MembersInjectors

从 Dagger 2.14.1 开始也会发生这种情况。这种情况仅发生在我包含的库中的

MyClass

如果我使用

-dontwarn com.mypackage.MyClass_Factory

然后它会在运行时崩溃

java.lang.NoSuchMethodError: No static method injectMembers(Ldagger/MembersInjector;Ljava/lang/Object;)Ljava/lang/Object; in class Ldagger/internal/MembersInjectors; or its super classes (declaration of 'dagger.internal.MembersInjectors' appears in MyClass

这意味着来自 Proguard 的警告是我应该小心的合法警告。

我搜索并发现问题报告于https://github.com/google/dagger/pull/950#issuecomment-353223029

@ronshapiro 的解决方案是

您应该遮蔽其中一个(或两个)库中的

dagger.internal
。旧的可能是最简单的

shade the dagger.internal
是什么意思?如何解决我的问题?

java android jar dagger-2
1个回答
0
投票

着色是打包库依赖项的一部分:您可以使用重写工具重新打包该库,以将 Dagger 2.13 中的

dagger.internal
包含在新名称(例如
librarynamehere.shaded.dagger.internal
)下,从而更改库内的所有引用以使用新名字。这将允许
dagger.internal
的两个版本在您的库中共存,但只有当您无法升级 Dagger 版本以使其在库和应用程序中匹配时,您才应该尝试此操作。


这个答案所示,Dagger 2.14 中的重构删除了 MembersInjector.injectMembers 方法。使用 2.14 及更高版本生成的代码不应调用此方法。

这里发生的情况是,您正在使用的库已经打包了 Dagger 生成的代码,该代码假定存在

MembersInjector.injectMembers
,就像 2.14 之前的版本一样。升级到2.19后,该方法消失了,因此生成的代码已损坏。

这特别棘手,因为删除此方法可以说是一个语义版本控制破坏性更改,但有一个较小的版本增加,包管理库可能会认为这是非破坏性的。公平地说,Dagger 的意图是库不发送生成的代码,而是记录其用法或允许使用应用程序使用匹配的库生成代码:

无法保证生成的代码(即工厂)在不同版本之间可以很好地协同工作。我们没有任何方法来测试这一点。一般来说,任何打算串联使用 Dagger 的库都使用相同版本的 Dagger,这是一个好主意。

如果一个库你不拥有正在将Dagger代码生成传递给你并且没有记录它,那么对于库所有者来说这是一个坏主意。

如果您可以选择使用较新版本的 Dagger 升级或重新编译库,最好是与您正在使用的 Dagger 外部版本相匹配的版本,那么这将解决问题。同样,如果您要保留 Dagger 的外部版本以匹配依赖项中的版本。这些会比阴影更理想。

如软件工程 SE 问题 什么是“阴影”Java 依赖项?,阴影是指使用 jarjar 等工具重新打包和/或重命名 Java 资源。这里的想法是将 2.13

dagger.internal
库的副本与依赖项一起打包,重写库中的字节码以使用重新打包版本的 Dagger 而不是新版本。

但是,最便宜(但最脆弱)的解决方案是“影子”:在源目录中添加一个文件,以匹配

dagger/internal/MembersInjectors.java
匹配您正在使用的Dagger版本,但阅读缺少的injectMembers方法
。假设您的构建系统在设置类路径时更喜欢本地文件而不是依赖项,则您的本地文件将在 Dagger 提供的等效文件之前找到。这可能有效,但稍后可能会成为合并危险,并且如果 MembersInjectors 在较新版本的 Dagger 中发生更改,则可能会导致奇怪的错误:我只会针对非常临时的代码尝试此操作。
另请参阅:

Java 类阴影和着色

,Ammar Khaku 在 Medium 上

© www.soinside.com 2019 - 2024. All rights reserved.