Android D8编译报错:Program type already present: GwtCompatible
嘿,这个错误我太熟了——本质就是依赖冲突:你的项目里有多个库都包含了com.google.common.annotations.GwtCompatible这个类,D8在合并DEX文件的时候发现重复类,直接就报错了,对应的:app:transformDexArchiveWithExternalLibsDexMergerForFlavorDevDebug任务失败也正好印证了这一点,毕竟这个任务就是负责把第三方库的DEX合并到一起的。
下面给你一步步排查和解决的方法:
1. 精准揪出重复依赖的来源
你已经跑了./gradlew app:dependencies,但可以用更针对性的命令,直接过滤出和Guava相关的依赖(因为GwtCompatible是Guava库的类):
./gradlew app:dependencies --configuration flavorDevDebugAndroidTestCompileClasspath | grep -A 5 -B 5 "guava"
这个命令会帮你在flavorDevDebugAndroidTestCompileClasspath配置下,找出所有引入Guava的依赖路径,你能一眼看到哪些库间接带了不同版本的Guava。
2. 手动排除重复的依赖
找到重复引入Guava的库之后,在app/build.gradle里给对应的依赖加上exclude规则,把重复的Guava模块去掉。比如如果发现some-third-party-lib引入了Guava,你可以这么写:
dependencies { androidTestImplementation('com.example:some-third-party-lib:2.0.0') { // 排除标准Guava exclude group: 'com.google.guava', module: 'guava' // 如果是安卓专用版的Guava,就换成下面这条 // exclude group: 'com.google.guava', module: 'guava-android' } }
注意:记得保留一个最适配你项目的Guava版本(一般建议选最新稳定版,或者和项目核心库兼容的版本)。
3. 强制统一所有Guava版本
要是排查起来太麻烦,也可以直接在项目根目录的build.gradle里强制指定Guava版本,让所有依赖都用同一个版本:
allprojects { repositories { // 你的仓库配置(比如google()、mavenCentral()) } configurations.all { resolutionStrategy { // 替换成你需要的Guava版本,这里用安卓专用版举例 force 'com.google.guava:guava:31.0.1-android' } } }
这个方法会直接覆盖所有依赖引入的Guava版本,从根源上杜绝重复类的问题。
4. 重点检查测试相关依赖
因为你的错误是在flavorDevDebugAndroidTestCompileClasspath配置下出现的,一定要留意Android Test相关的依赖(也就是androidTestImplementation里的库)——很多时候测试库(比如Espresso、Mockito的某些版本)会和主代码库引入重复的Guava,这部分要重点排查。
内容的提问来源于stack exchange,提问作者MiguelSlv




