Gradle如何禁用zxing依赖中不需要的Maven build-android Profile?
问题背景
项目中引入zxing依赖如下:
compile('com.google.zxing:core:3.4.1') compile('com.google.zxing:javase:3.4.1')
报错原因是core-3.4.1.pom继承的zxing-parent-3.4.1.pom中存在一个id为build-android的Maven Profile,该Profile会在存在ANDROID_HOME环境变量且JDK版本低于9时激活,但是该Profile定义的com.google.android:android依赖的systemPath引用了变量,非Android环境未配置ANDROID_HOME时,会导致路径解析失败,抛出如下错误:
Task :compileJava Errors occurred while build effective model from C:\Users\eXtensia.gradle\caches\modules-2\files-2.1\com.google.zxing\core\3.4.1\d1e7c4667f9dcdda30d09f3df7d1b44f65c44336\core-3.4.1.pom: 'dependencyManagement.dependencies.dependency.systemPath' for com.google.android:android:jar must specify an absolute path but is ${env.ANDROID_HOME}/platforms/android-22/android.jar in com.google.zxing:core:3.4.1 Errors occurred while build effective model from C:\Users\eXtensia.gradle\caches\modules-2\files-2.1\com.google.zxing\javase\3.4.1\357121cdf3f89f63ddfaad18170612dcad0db947\javase-3.4.1.pom: 'dependencyManagement.dependencies.dependency.systemPath' for com.google.android:android:jar must specify an absolute path but is ${env.ANDROID_HOME}/platforms/android-22/android.jar in com.google.zxing:javase:3.4.1
问题解答
1. 如何禁止Gradle构建时激活该Maven Profile?
可以直接通过Gradle全局属性禁用指定Maven Profile,在项目根目录的gradle.properties文件中添加如下配置即可:
maven.profile.exclude=build-android
该配置会让Gradle在解析POM文件时直接排除id为build-android的Profile,不会加载其内部的依赖管理配置,即可解决路径报错问题。如果是单次构建临时禁用,也可以在构建命令中添加参数:
./gradlew build -Dmaven.profile.exclude=build-android
2. Gradle有没有方式自动修改下载的POM文件移除无效配置?
可以通过Gradle的依赖元数据替换功能实现,在build.gradle中添加如下配置,即可在解析zxing父POM时自动移除指定Profile:
dependencies { components { withModule('com.google.zxing:zxing-parent') { allVariants { withPom { pom -> def profiles = pom.asNode().get("profiles") as List profiles.each { profileNode -> profileNode.children().removeAll { it.attribute("id") == "build-android" } } } } } } // 原有依赖配置保持不变 implementation 'com.google.zxing:core:3.4.1' implementation 'com.google.zxing:javase:3.4.1' }
该配置会在依赖解析阶段动态修改加载到的zxing-parent POM内容,删除build-android Profile,不需要修改本地缓存的POM文件,对项目其他依赖无影响。
3. 如何修改zxing-parent POM适配所有场景?
可以对build-android Profile的激活条件和依赖配置做如下优化:
- 首先给Profile的激活条件增加显式启用开关,新增一个
zxing.build.android的属性判断,只有当该属性显式设置为true时才触发激活,避免未配置ANDROID_HOME的环境误触发:
<activation> <property> <name>zxing.build.android</name> <value>true</value> </property> <property> <name>env.ANDROID_HOME</name> </property> <jdk>[,9)</jdk> </activation>
- 其次给
android.home变量添加默认值兜底,避免变量未解析时路径无效:
<properties> <android.home>${env.ANDROID_HOME}</android.home> <android.platform>22</android.platform> </properties>
- 也可以将android依赖从
dependencyManagement节点移到android相关子模块内部,父POM中不声明该系统依赖,避免父POM被非Android模块继承时加载到无效配置。
修改后,Android用户需要编译Android相关模块时,只需要在构建命令中添加-Dzxing.build.android=true即可激活Profile,非Android用户默认不会触发该Profile加载,同时兼容Maven和Gradle的解析逻辑。
内容的提问来源于stack exchange,提问作者timguy

