无法找到引用的方法'java.lang.Object injectMembers(dagger.MembersInjector,java.lang.Object)'。

10

最近我将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。旧版本可能最容易

“隐藏dagger.internal”的意思是什么?怎样解决我的问题?


你能告诉我解决方案吗? - Shubham Anand
1个回答

0

Shading 是打包库依赖项的一部分:您可以使用重写工具重新打包该库,以包含 Dagger 2.13 中的 dagger.internal,并将其命名为新名称(例如 librarynamehere.shaded.dagger.internal),以更改库内部的所有引用以使用新名称。这将允许两个版本的 dagger.internal 在您的库中共存,但仅当您无法升级库和应用程序中的 Dagger 版本以匹配时才应尝试此操作。


就像这个答案中所述,Dagger 2.14中的重构删除了方法MembersInjector.injectMembers。使用2.14及以上版本生成的代码不应该调用此方法。

这里发生的情况是,您正在使用的库已经打包了假定在2.14之前存在MembersInjector.injectMembers的Dagger生成的代码。升级到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版本中发生更改,则可能会导致奇怪的错误:我只会尝试对非常临时的代码使用此方法。

另请参见:Ammar Khaku在Medium上的Java Class Shadowing and Shading


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接