AAR发布至Maven仓库时本地子模块依赖解析失败问题
Android AAR发布时本地Module依赖version为unspecified导致解析失败的解决方案
问题根因
出现该异常是两个配置缺失共同导致的:
- 本地依赖的
:CameraModule、:VideoTranscoderModule未配置Maven发布坐标,maven-publish插件自动生成pom时,会给这类本地project依赖填充默认值:groupId取根工程名myapp-android、version固定为unspecified - 仅发布了主SDK的AAR包,两个子模块未作为独立构件上传至Maven仓库,消费端拉取传递依赖时无法在任何配置的仓库中找到对应坐标的构件
另外你当前主模块发布配置中使用from components.debug也是不规范的,debug变体的依赖scope生成逻辑和正式release变体存在差异,容易出现依赖节点生成异常,正式发布必须替换为release变体。
可选方案一:子模块作为独立构件一同发布
如果两个子模块需要被其他工程独立引用,选择该方案:
- 分别给两个子模块配置独立的maven-publish发布规则,坐标和主SDK保持同groupId、同version即可,示例配置(以CameraModule为例,VideoTranscoderModule仅需修改artifactId):
// 对应子模块的build.gradle apply plugin: 'maven-publish' afterEvaluate { publishing { publications { releaseAar(MavenPublication) { from components.release groupId = "com.myapp.sdk" artifactId = "cameramodule" version = "1.1.2" } } // 复用主模块配置的Nexus仓库信息 repositories { maven { name = "mynexusrepo" credentials { username = "username123" password = "123password" } url = uri("http://localhost:8081/repository/maven-releases/") allowInsecureProtocol = true } } } }
- 修改主SDK的发布配置,将
from components.debug替换为from components.release - 发布时先执行两个子模块的上传任务,再执行主SDK的上传任务,此时自动生成的pom会自动替换子模块的依赖坐标为你配置的有效值,消费端开启传递依赖时会自动从Nexus拉取对应子模块的AAR,不会再报找不到依赖。
可选方案二:子模块合并入AAR(Fat AAR模式)
如果两个子模块只是主SDK的内部实现,不需要作为独立依赖对外暴露,直接将子模块的代码、资源合并入主AAR即可,此时pom中不会生成子模块的依赖节点,从根源避免依赖解析问题。
配置步骤:
- 在根工程build.gradle中添加Fat AAR插件依赖:
buildscript { repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.4.2' // 保持和你当前AGP版本匹配 classpath 'com.kezong:fat-aar:1.3.8' } }
- 在主SDK模块的build.gradle顶部应用Fat AAR插件:
apply plugin: 'com.kezong.fat-aar'
- 将主模块对子模块的依赖声明从
implementation改为embed,第三方远程依赖保持原有implementation配置不变:
embed project(':CameraModule') embed project(':VideoTranscoderModule') implementation "joda-time:joda-time:2.10.1"
- 同样将主模块发布配置中的
from components.debug替换为from components.release,执行发布任务即可。最终生成的AAR会包含两个子模块的所有代码与资源,消费端仅需引入主SDK即可正常使用,不需要额外下载子模块。
不推荐的临时方案
可以通过pom修改逻辑在生成阶段直接删除version为unspecified的依赖节点,配置示例:
// 加在主模块publishing的pom配置块内 pom.withXml { asNode().dependencies.'*'.findAll { dep -> dep.version.text() == 'unspecified' }.each { dep -> dep.parent().remove(dep) } }
注意:该方案仅做参考,未合并子模块代码的情况下直接删除依赖节点会导致运行时类缺失,生产环境禁止使用。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

