一 前言
2025年9月15日更新,删除旧版废弃的插件说明,更新编译环境,基于Gradle 8.0, AGP 8.1.0。
Maven Publish Plugin(新版)
官方文档
此文章主要介绍如何在AndroidStudio中配置Maven Publish Plugin插件发布工件到私服仓库中。
二 使用Maven Publish Plugin插件
Maven Publish Plugin通过项目中以publishing命名,PublishingExtension类型的扩展来实现。该扩展提供了一个称为publications的容器和一个称为repositories的容器,Maven Publish Plugin适用于MavenPublication发布和MavenArtifactRepository仓库。
使用Maven Publish Plugin,需要在构建脚本中添加以下代码引入并启用插件
- build.gradle
apply plugin: 'maven-publish'
// 高版本Gradle可以使用以下脚本引用
plugins {
id 'maven-publish'
}
2.2 出版物(Publications)
出版物对象描述创建的出版物的结构/配置,出版物通过任务发布到仓库存储,出版物配置明确发布内容。项目中的出版物都在 PublishingExtension.getPublications()容器中定义。
要使Maven Publish Plugin生效,必须将MavenPublication添加到出版物集合中,此出版物确定发布的工件以及关联的POM文中包含的详细信息。出版物可以通过添加组件、自定义工件以及修改生成的POM文件来配置发布。
2.3 发布程序组件(Publishing a Software Component)
发布Gradle项目到Maven仓库最简单的方式,就是通过SoftwareComponent来发布。该组件目前支持的出版物包括:
| 名称 | 内容提供者 | 工件 | 依赖 |
|---|---|---|---|
| java | Java Plugin | 生成jar文件 | 依赖来自runtime配置 |
| web | War Plugin | 生成war文件 | 没有依赖 |
2.4 在AndroidStudio中发布到远程仓库
2.4.1 手动指定发布工件和使用pom 文件关联依赖
旧版的 maven 插件无需自己定义发布内容和 pom,插件会直接将编译输出的 aar 作为发布内容,并且根据 build.gradle 声明的依赖生成 pom 文件。然而新的 maven-publish 插件需要手动指定发布内容和 pom 文件内容。可以在声明出版物的时候,通过 artifact 进行指定(同时发布多个工件使用 artifacts,更多详情请参考 MavenPublication 文档说明),手动配置 pmo 文件可以在出版物声明时使用 pom.withXml{} 声明即可。如下示例所示(在AndroidStudio中使用):
apply plugin: 'maven-publish'
publishing {
repositories {
maven {
credentials {
username 'username' // 仓库发布用户名
password 'password' // 仓库发布用户密码
}
url 'trunk_url' // 仓库地址
}
}
publications {
maven(MavenPublication) {
groupId 'group_id' // groupId
artifactId 'artifact_id' // artifactId
version '1.0.0' // 发布版本
description 'This is a liberary to test v1.0.0' // 说明描述
artifact "${project.buildDir}/outputs/aar/${project.name}-release.aar"
pom.withXml{
def dependenciesNode = asNode().appendNode("dependencies")
// 添加一个依赖
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dependency.group)
dependencyNode.appendNode('artifactId', dependency.name)
dependencyNode.appendNode('version', dependency.version)
// 逐一添加第三方依赖。。。
}
// 如果依赖比较多,有个更简洁的方式就是读取配置的依赖配置,逐一添加。这种方法在依赖变更之后,也会自动识别,如下所示
// pom.withXml{
// def dependenciesNode = asNode().appendNode("dependencies")
// configurations.implementation.allDependencies.forEach(){
// Dependency dependency ->
// if (dependency.version != "unspecified" && dependency.name != "unspecified"){
// def dependencyNode = dependenciesNode.appendNode('dependency')
// dependencyNode.appendNode('groupId', dependency.group)
// dependencyNode.appendNode('artifactId', dependency.name)
// dependencyNode.appendNode('version', dependency.version)
// }
// }
// }
}
}
}
2.4.2 添加配置自动获取发布工件和生成 pom 文件关联依赖
首先,需要再在库模块下的build.gradle 文件中的android声明出版物名称,可以使用 singleVariant() 或 multipleVariants() 指定的名称。例如在xxx-library/build.gradle中添加以下声明:
apply plugin: 'com.android.library'
//....
android {
//....
publishing {
// 此处声明了名为release的共建,才能在后续自动发布工件中使用
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
}
}
Maven Publish Plugin一样可以从上面配置生成的工件中自动获取工件并生成 pom 文件关联依赖,代码如下:
publishing {
repositories {
maven {
credentials {
username 'username' // 仓库发布用户名
password 'password' // 仓库发布用户密码
}
url 'trunk_url' // 仓库地址
}
}
}
afterEvaluate {
publishing {
publications {
release(MavenPublication) {
publications {
release(MavenPublication) {
// 添加以下配置可以自动从编译容器中获取release版本内容并生成pom文件,但是需要注意的是,
// 在AGP 8.0之后,需要在库模块中使用 `singleVariant()` 或 `multipleVariants()` 声明名为`release`的工件
// 注意:发布物声明必须在 afterEvaluate 内部,因为 components 在 afterEvaluate 阶段才生成完成
from components.release
groupId _groupId // groupId
artifactId _artifactId // artifactId
version versionName // 发布版本
description _description // 说明描述
}
}
groupId 'group_id' // groupId
artifactId 'artifact_id' // artifactId
version '1.0.0' // 发布版本
description 'This is a liberary to test v1.0.0' // 说明描述
}
}
}
}
说明:通过
components.release可以自动从编译容器中获取名称为release的工件,并生成pom文件。但是需要注意的是:使用components.release必须将配置代码放在afterEvaluate {}中,因为编译容器中的内容只有在afterEvaluate阶段才生成完成。另外,需要在库模块下的build.gradle文件的android闭包中使用使用singleVariant()或multipleVariants()添加名为release的publishing出版物。否则会出现异常:Could not get unknown property 'release' for SoftwareComponentInternal set of type org.gradle.api.internal.component.DefaultSoftwareComponentContainer.
配置好后,打开Gradle面板,双击模块名称/Tasks/publishing/publishMavenPublicationToMavenRepository任务或者在命令行输入gradle 模块名称:publishMavenPublicationToMavenRepository执行命令发布到远程仓库,如果出现BUILD SUCCESS字样说明发布成功。
2.4.3 处理依赖传递问题
依赖传递是使用仓库的一个便利之处,就是我们只需要引入某个库的依赖,这个库所依赖的其他依赖项,都会自动依赖到项目中,完成这一个功能主要依靠 pom.xml 文件的配置信息。 pom.xml 文件中声明了关联的所有依赖,其中 <scope> 节点定义了依赖的传递类型,其中包括以下几种:
compile:依赖在编译时起作用,具有传递性;provided:依赖在编译或者测试时起作用,跟compile类似,但是无传递性;runtime:依赖在运行时或者测试时起作用,编译时不起作用,不具备传递性;test:依赖在测试时起作用,运行时不起作用;system:跟provided非常类似,主要不同之处是system需要我们在系统中直接指定一个特定的jar,需要配合<systemPath>使用,这个 scope 已经废弃。import:Maven 2.0.9 之后新增,仅在依赖类型为pom时(由<type>节点指定)有用。表示此项依赖将会被pom文件中所有有效的依赖替代。
其实我们常用的是上面的四种,对于手动生成 pom 文件,可以根据需求进行手动指定映射,但是对于自动生成 pom 文件的情况,我们就必须清楚在 AndroidStudio 的依赖声明中,依赖类型默认映射是怎样的,才能准确实现依赖传递。下面是常用的部分
| AndroidStudio依赖类型 | Maven 依赖类型 |
|---|---|
implementation | runtime |
api | compile |
provided | provided |
runtimeOnly | runtime |
compileOnly | - |
testImplementation | - |
从前面的介绍我们知道,Maven 中只有 compile 依赖才具有传递性,因此,在AndroidStudio中使用 maven-pulbish 插件发布工件,如果使用自动生成 pom 文件,那么就需要在 build.gradle 文件中声明依赖是,对需要传递的依赖使用 api 来声明。
__注意事项:旧版的
maven插件的映射有所不同,其中implementation映射为compile,因此如果你的项目从旧版迁移到新版插件,切记一定要修改依赖声明,否则会出现需要传递的依赖无法传递的问题。<scope>节点未指定时,默认为compile,如果手动生成pom文件,没有指定<scope>将采用默认值,但是建议显式指定<scope>值。 __
三 错误及解决方案
3.1 发布出现Read timeout网络异常
报错信息似以下的例子
Upload http://192.168.33.110:8081/repository/RastarGameSdkOversea/com/test/maven/plugin/rastar-sdk-line/1.0.0/rastar-sdk-line-1.0.0.pom
Could not transfer artifact com.test.maven.plugin:rastar-sdk-line:pom:1.0.0 from/to remote (http://192.168.33.110:8081/repository/RastarGameSdkOversea/): Could not write to resource 'com/test/maven/plugin/rastar-sdk-line/1.0.0/rastar-sdk-line-1.0.0.pom'
:rsdk_line:publishAarPublicationToMavenRepository FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':rsdk_line:publishAarPublicationToMavenRepository'.
> Failed to publish publication 'aar' to repository 'maven'
> Could not write to resource 'http://192.168.33.110:8081/repository/RastarGameSdkOversea/com/test/maven/plugin/rastar-sdk-line/1.0.0/rastar-sdk-line-1.0.0.pom'.
> Read timed out
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 44s
根据报错信息,是设置了代理,检查AnroidStudio是否设置了代理,如果没有,打开Gradle用户目录(一般是在C:\Users\用户名\.gradle),打开gradle.properties文件,看看是否设置了代理,如果设置了,将其去掉。
- 在Gradle用户目录下
gradle.properties设置代理的配置如下。
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=1080
3.2 ERROR: Cannot configure the 'publishing' extension after it has been accessed.
配置好后,刷新Gradle的时候,如果出现ERROR: Cannot configure the 'publishing' extension after it has been accessed.错误,可以将以上的配置修改一下
apply plugin: 'maven-publish'
publishing {
repositories {
maven {
credentials {
username 'username' // 仓库发布用户名
password 'password' // 仓库发布用户密码
}
url 'trunk_url' // 仓库地址
}
}
publications {
maven(MavenPublication) {
groupId 'group_id' // groupId
artifactId 'artifact_id' // artifactId
version '1.0.0' // 发布版本
description 'This is a liberary to test v1.0.0' // 说明描述
}
}
}
将多级闭包改为少一级,将publishing跟闭包下面的使用.链接在一起,如下:
apply plugin: 'maven-publish'
publishing.repositories {
maven {
credentials {
username 'username' // 仓库发布用户名
password 'password' // 仓库发布用户密码
}
url 'trunk_url' // 仓库地址
}
}
publishing.publications {
maven(MavenPublication) {
groupId 'group_id' // groupId
artifactId 'artifact_id' // artifactId
version '1.0.0' // 发布版本
description 'This is a liberary to test v1.0.0' // 说明描述
}
}
3.3 使用新版插件后依赖传递失效了
发布时,当前库依赖的一些第三方库,切实远程仓库依赖,需要传递给当前库的引用者,但是发现依赖声明的那些依赖都不会传递给引用者了,此时可以查看下仓库中的 pom 文件,看看 <scope> 节点的值是否为 compile,如果不是,就需要检查你发布时生成 pom 的文件,如果是使用自动生成 pom 文件,则需要检查项目依赖声明,将所有的 implementation 改为 api 即可(新版本的 maven-publish 插件默认将 implementation 映射成 runtime),详情参考:2.4.3 处理依赖传递问题
3.4 运行出现出现异常:Could not get unknown property 'release' for SoftwareComponentInternal set of type org.gradle.api.internal.component.DefaultSoftwareComponentContainer.
这是因为自动获取工件发布的时候,找不到名称为release的工件,必须在库模块下的build.gradle的android闭包中添加工件声明,可以使用 singleVariant() 或 multipleVariants() 指定的名称。当然,你也可以指定其他名称。详情参考:2.4.2 添加配置自动获取发布工件和生成 pom 文件关联依赖

本文详细介绍如何使用Gradle的MavenPlugin和MavenPublishPlugin发布工件到Maven仓库,涵盖配置、任务、依赖管理和POM文件生成,特别针对Android Studio的发布流程进行了深入解析。
1675

被折叠的 条评论
为什么被折叠?



