AndroidStudio使用Maven Publish Plugin发布工件到Maven仓库

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

一 前言

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来发布。该组件目前支持的出版物包括:

名称内容提供者工件依赖
javaJava Plugin生成jar文件依赖来自runtime配置
webWar 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() 添加名为releasepublishing出版物。否则会出现异常: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 依赖类型
implementationruntime
apicompile
providedprovided
runtimeOnlyruntime
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.gradleandroid闭包中添加工件声明,可以使用 singleVariant()multipleVariants() 指定的名称。当然,你也可以指定其他名称。详情参考:2.4.2 添加配置自动获取发布工件和生成 pom 文件关联依赖

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值