Gradle Maven-Publish插件默认不向POM发布API/Implementation依赖问题
Hey,我懂你碰到的这个坑——Gradle的maven-publish插件默认确实不会把api或者implementation这些依赖自动写到POM里,你之前的代码没生效大概率是因为用了已经废弃的configurations.compile配置,现在Gradle 7+早就不用这个了。我给你两个实用的解决办法,你可以根据自己的项目情况选:
解决方案1:手动遍历正确的依赖配置生成POM节点
如果你不想改动项目插件结构,可以修改你的pom.withXml代码,遍历api和implementation这两个当前有效的配置,同时给它们设置对应的POM scope:
publishing { publications { mavenJava(MavenPublication) { from components.java pom.withXml { def dependenciesNode = asNode().appendNode('dependencies') // 处理api依赖,对应POM中的compile scope configurations.api.allDependencies.each { dep -> // 过滤掉没有groupId或artifactId的异常依赖 if (dep.group != null && dep.name != null) { def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) dependencyNode.appendNode('version', dep.version ?: '') dependencyNode.appendNode('scope', 'compile') } } // 处理implementation依赖,对应POM中的runtime scope configurations.implementation.allDependencies.each { dep -> if (dep.group != null && dep.name != null) { def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) dependencyNode.appendNode('version', dep.version ?: '') dependencyNode.appendNode('scope', 'runtime') } } } } } }
这里要注意过滤掉group或name为空的依赖,避免生成无效的POM节点;另外如果你的依赖有exclude规则,也可以在这个逻辑里添加对应的<exclusions>节点。
解决方案2:启用Java Library插件(官方推荐)
如果你的项目是一个供其他模块依赖的类库,更推荐你直接启用java-library插件——它会自动帮你处理api和implementation依赖到POM scope的映射,完全不用手动写XML处理代码:
plugins { id 'java-library' id 'maven-publish' } // 这里写你的依赖配置,比如: dependencies { api 'com.google.guava:guava:32.1.3-jre' implementation 'org.apache.commons:commons-lang3:3.14.0' } publishing { publications { mavenJava(MavenPublication) { from components.java } } }
启用java-library插件后,maven-publish会自动把api依赖标记为POM中的compile scope(消费者编译时就能拿到),把implementation依赖标记为runtime scope(消费者运行时才需要),这是Gradle官方为类库项目设计的最佳实践,比手动维护XML节点靠谱多了。
如果你的项目是普通Java应用(不是类库),那可以考虑把implementation替换成compileOnly或者调整依赖策略,不过一般来说,发布带依赖的POM大多是类库场景,所以方案2应该能解决你的问题。
内容的提问来源于stack exchange,提问作者bj4947

