Gradle无法解析含RELEASE版本Maven父依赖的Project B问题求助
我有个Maven项目Project B,它的pom.xml依赖父项目Project A,配置是这样的:
<parent> <groupId>org.company</groupId> <artifactId>projectA</artifactId> <version>RELEASE</version> </parent> <artifactId>projectB</artifactId> <version>0.0.1</version>
现在我用Gradle 4.5新建了Project C,想把Project B作为依赖加进去,build.gradle写了这些:
repositories { maven { url "http://mycompany:8081/artifactory/repository" } } dependencies { compile group: 'org.company', name: 'projectB', version: '0.0.1' }
结果构建报错了:
Could not resolve org.company:projectB:0.0.1.
Could not parse POM http://company:8081/artifactory/repository/org/company/projectB/0.0.1/projectB-0.0.1.pom
Could not find org.company:projectA:RELEASE
其他Maven项目都能正常找到对应版本,我不想把Project A的版本改成具体数值,也不想拉取Project A的最新版,能不能让Gradle像Maven那样正确解析RELEASE版本?或者有没有办法直接下载Project B的完整jar包就行?本地用的是Gradle 4.5和Maven 3.5.2。
1. 让Gradle按Maven规则解析RELEASE版本
Gradle默认对Maven的RELEASE、LATEST这类特殊版本标签支持不够,你可以在build.gradle里配置解析策略,让它像Maven一样读取仓库的元数据来确定RELEASE对应的具体版本:
repositories { maven { url "http://mycompany:8081/artifactory/repository" // 优先读取POM和元数据,再读artifact metadataSources { mavenPom() artifact() } // 限定只在这个仓库找公司内部的依赖 content { includeGroup 'org.company' } } // 如果本地Maven仓库有Project A的RELEASE版本,加上这个能加快解析 mavenLocal() } // 配置版本解析逻辑,处理RELEASE标签 configurations.all { resolutionStrategy { // 禁用缓存,确保每次都拉最新的元数据(可选,根据需求调整) cacheChangingModulesFor 0, 'seconds' eachDependency { details -> if (details.requested.version == 'RELEASE') { // 从仓库元数据里获取RELEASE对应的具体版本号 def resolvedVersion = metadata().getVersion(details.requested.group, details.requested.name, 'RELEASE') details.useVersion resolvedVersion } } } }
不过Gradle 4.x的版本解析能力不如高版本,如果这个配置没生效,试试下面的方法。
2. 直接下载Project B的jar包,跳过POM解析
如果你的核心需求就是拿到Project B的jar包,不需要处理它的父POM依赖,那可以直接指定只下载jar,跳过POM的解析步骤:
dependencies { // 明确指定只下载jar格式的依赖 compile group: 'org.company', name: 'projectB', version: '0.0.1', ext: 'jar' }
或者更强制一点,直接让Gradle忽略POM,只拉jar:
configurations.all { resolutionStrategy { eachDependency { details -> if (details.requested.name == 'projectB') { // 使用@jar后缀,告诉Gradle只下载jar details.useTarget "org.company:projectB:0.0.1@jar" } } } }
这样Gradle就不会去解析Project B的POM,自然也就不会去找Project A的RELEASE版本了。
3. 复用Maven的配置文件
既然你的Maven能正常工作,说明~/.m2/settings.xml里有正确的仓库配置(比如Artifactory的认证、镜像),可以让Gradle直接导入这个配置,复用Maven的解析逻辑:
apply plugin: 'maven' // 读取Maven的settings.xml def mavenSettings = new XmlSlurper().parse(new File(System.getProperty('user.home') + '/.m2/settings.xml')) repositories { maven { url mavenSettings.mirrorOf.find { it.text() == '*' }?.url?.text() ?: "http://mycompany:8081/artifactory/repository" // 如果settings里有仓库认证信息,加上这个 credentials { username mavenSettings.servers.server.find { it.id == 'artifactory' }?.username?.text() password mavenSettings.servers.server.find { it.id == 'artifactory' }?.password?.text() } } }
这样Gradle就会用和Maven一样的配置去访问仓库,自然就能正确解析RELEASE版本了。
4. 检查Artifactory的元数据
Maven能正常解析,说明Artifactory里已经生成了maven-metadata.xml文件,里面记录了RELEASE对应的具体版本号。你可以手动访问一下Project A的仓库路径(比如http://mycompany:8081/artifactory/repository/org/company/projectA/maven-metadata.xml),确认这个文件存在且内容正确。如果Gradle访问不到这个文件,可能是仓库权限或者路径配置的问题,需要和运维确认一下。
内容的提问来源于stack exchange,提问作者Borja Gorriz

