在启用 R8 的模块中发现重复的类
Posted
技术标签:
【中文标题】在启用 R8 的模块中发现重复的类【英文标题】:Duplicate class found in modules with R8 enabled 【发布时间】:2019-12-21 22:36:40 【问题描述】:我创建了两个 aar 库:com.example:test1:1.0.0 和 com.example:test2:1.0.0。我将这些库添加到我的主应用程序中,构建 android-Studio 后抛出错误:
Duplicate class com.example.utils.a found in modules classes.jar (com.example:test1:1.0.0) and classes.jar (com.example:test2:1.0.0)
我发现这个错误发生是因为两个库在同一个包(com.example.utils)中都有类,并且在混淆后 R8 创建了具有相同全名的类(a.class)(我在 aar 的 classes.jar 中看到了这个)。如果我在我的库的属性中禁用 R8,这个错误就会消失。
'a' 不是库类:经过混淆处理后,所有库类名称保持不变,并且 a.class 由 R8 额外添加到包中。 我阅读了 R8 文档并没有发现任何关于这个问题的信息。 有什么方法可以解决这个问题,而无需在我的一个库中重新命名包?
【问题讨论】:
我不认为这个问题不好,但考虑也可以发布一些代码,考虑发布模块,甚至展示你在“混淆后 R8 创建具有相同完整的类 (a.class) 之后看到的内容”名称“ 您可以通过删除其中一个库中的文件或使用使用相同类的版本来解决此问题。 我认为他们想知道为什么这是一个问题,而不是找到解决问题的方法“有没有什么方法可以解决这个问题,而无需在我的一个库中重新命名包?” @BlindKai @a_local_nobody 我唯一遇到这个问题是当我尝试将官方库与另一个使用 off.lib 的库一起使用时。班级。所以我不能肯定地说。但这是一个问题,因为编译器无法选择使用哪个类。 【参考方案1】:在创建两个库时,最好使用两个不同的命名空间,否则即使不使用 R8,当“意外”将同名的类添加到两者时,也可能会出现重复的类。所以在你的情况下使用com.example.test1
和com.example.test2
。
根据您的用例,不将 R8 应用于库,而仅将 R8 应用于包括两个库的最终应用程序也可能是更好的选择。收缩库主要是为了缩小发行版的大小,并重命名内部结构以避免图书馆用户(无意或有意)依赖内部结构,这可能会在库版本之间发生变化。
缩小库时,您还需要考虑选项-keeppackagenames
以确保所有重命名的类都保留在库的包中。否则,您可能会以课程结束,例如a.a.a.a.class
在多个库中。
如果此问题发生在您无法控制诸如 shadow 之类的工具的库中,则可以使用重新定位。
【讨论】:
【参考方案2】:您应该始终为 Java 或其他 JVM 语言的所有代码添加 unique 包前缀,以创建唯一的 fully qualified name,因为任何两个具有完全相同的完全限定名称的类都会导致构建错误.发生这种情况是因为 JVM 仅使用最初保存在单个表中的完全限定名称字符串来实例化系统中的所有类和接口。如果表将有一个类/接口的多个条目,它将不知道选择哪一个。你可以阅读更多关于它的信息here。
正如我在回答here 中所描述的,与混淆相关的冲突的最佳解决方案是在每个库的proguard-rules
文件中使用-repackageclasses com.example:test#.ofs
,同时将#
分别替换为1
和2
。这会将所有经过混淆的类移动到 com.example:test#.ofs
包中,而所有未混淆的类将保留在其原始包中,并且保证不会发生冲突。
正如 Proguard documentation 所说:
-repackageclasses [package_name]
指定重新打包所有重命名的类文件,方法是将它们移动到单个给定包中。
【讨论】:
以上是关于在启用 R8 的模块中发现重复的类的主要内容,如果未能解决你的问题,请参考以下文章
在模块中发现重复的类 com.mapbox.android.telemetry.AlarmReceiver。 Mapbox安卓工作室
Flutter 构建 apk:在模块 guava-26.0-android.jar 和 listenablefuture-1.0.jar 中发现了重复的类
在模块 guava-20.0.jar (com.google.guava:guava:20.0) 中发现重复的类 com.google.common.util.concurrent.Listenabl
在模块 jetified-com.google.zxing.client.android.captureactivity.jar 和 jetified-core-3.3.3.jar 中发现重复的类 c
在模块 jetified-okhttp-3.12.0 和 jetified-okhttp-ws-3.4.1 中发现重复的类 okhttp3.internal.ws.RealWebSocket
在模块类中找到重复的类 android.support.v4.app.INotificationSideChannel?