本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。
关于JCenter废弃这件事情,相信许多朋友早就已经知道了。我在几个月前也专门写过一篇文章分析JCenter废弃事件的前前后后,感兴趣的朋友可以去阅读下这篇文章 浅谈JCenter即将被停止服务的事件 。
在上面这篇文章当中提到了几个比较关键的点:
- 自2021年3月31日之后,JCenter就不再接受任何新库的提交。
- 自2022年2月1日之后,JCenter将停止提供库的下载服务。
- Google会在其Android开发者官网发布如何将开源库从JCenter迁出的方案。
当时整体的计划是这个样子的,然后几个月时间过去了,真是不得不说计划永远赶不上变化。
首先,Google修改了Android开发者官网的声明,没有再提到会给出迁出方案。只是告知开源库的发布者,以后发布库建议都发布到MavenCentral上。并告知开源库的使用者,你得自己去找这些库具体在哪里。
Google的这波操作可真是把锅甩的干干净净,JCenter废弃的事情与“我”再无关系,那是第三方开发者与JCenter之间的事情。
当时我看到Google修改声明之后心想,那这老库的迁移怎么办啊,Google是完全不管了。
不过再仔细一看,我才发现,原来JCenter也改了声明。在JCenter的最新声明中,2022年2月1日之后停止下载服务的那一条被删除了。也就是说,虽然JCenter不再允许开发者向其提交新的库,但是已经上传的老库会继续提供下载服务,这样也就不需要对它们做迁移了。
不知道为什么JCenter会改变态度做出这种善事,我猜测难不成是Google跟他们私下里进行了什么协商?不过不管怎么说,这对于开源库的开发者来说都是一件好事情,意味着老库的问题我们不需要再考虑了。
现在的问题就是,以后的新库怎么办?
为什么要使用MavenCentral
Google已经给出了其官方态度,建议开发者以后发布库都发布到MavenCentral上。
官方的态度其实是很重要的,因为以前JCenter也是这样被Google扶正的(结果Google被坑惨了),不然JCenter也无法在Android领域产生这么大的影响力。
如果你现在用最新版的Android Studio来创建一个新的项目,你会发现build.gradle文件中仓库的声明变成了这样:
代码语言:javascript复制allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
可以看到,mavenCentral()仓库成了创建项目时的默认仓库,而jcenter()仓库被标为了废弃。
许多国内的开发者可能会觉得MavenCentral太麻烦了,远不如JitPack用起来简单。
然而JitPack的问题就是并没有被Google官方推荐,你如果将库发布到JitPack上,开发者想要使用你的库,还得要额外引入一下JitPack的仓库才行,这无疑就增加了使用成本。
因此,即使是麻烦,我仍然建议广大开发者们要将自己的开源库发布到MavenCentral上。
那么接下来,我们就看看如何实现。
准备域名
相比于JCenter,MavenCentral的发布标准要远远高得多。不光是操作更麻烦的问题,而且MavenCentral还会对你是否拥有这个包路径所对应的域名进行检查。
比如你提交了一个库,它的包路径格式如下:
代码语言:javascript复制com.example.test:library:1.0.0
那么你就必须要拥有example.com这个域名才行。
相比之下,JCenter就完全不检查你是否真的拥有这个域名,谁先提交了使用这个包路径的库,这个包路径就是谁的了。
另外,注册自己的域名是要花钱的,如果你不想花钱的话也可以借助GitHub来完成,但是这样你的包路径就必须以io.github为前缀,而不能使用自定义的包路径了。
本篇文章介绍的是使用自己的域名来提交到MavenCentral的方式,如果你想要了解使用io.github域名的方式,可以参考这篇文章 发布Android Lib到Maven Central 。
那么不用多说,域名肯定是要自己先准备好的。我在阿里云上注册了一个叫guolindev.com的域名,因此我就可以使用以com.guolindev为前缀的包路径了。
创建工单
接下来访问以下地址去注册一个Sonatype账号:
https://issues.sonatype.org/secure/Dashboard.jspa
注册完之后重新访问该地址即可进入Sonatype Dashboard界面。
现在点击顶部工具栏上的Create按钮创建一个工单:
这个工单虽然看上去要填很多项内容,但其实还是非常简单的,我这里贴一下我当初填写的一个工单截图:
我们只需要填写带星号的必填项即可。
- Project和Issue Type保持默认选项,不用做修改。
- Summary可以随便填,这里我填写的是项目名称。
- Group Id非常重要,决定着库的包路径是什么。前缀使用你刚才申请好的域名的倒排方式,后面可以自定义一些与库名相关的路径。
- Project URL填写该项目的Github地址。
- SCM url只需要在上面的Github地址后面加上.git后缀即可。
点击Create完成工单创建。
创建完工单之后需要等待工作人员审核,我测试下来非工作时间是没人审核你的工单的。所以如果你是在周末创建的工单,那么可能需要等待两到三天的时间才会有人处理。
有工作人员处理你的工单之后,他会在你的工单里留下一条评论,如下图所示:
这条评论的意思就是,你要证明刚才你在Group Id里填写的包路径所对应的域名是你的。
证明的方式就是,在你的域名中添加一条类型为TXT的解析,并将它指向你这条工单的URL地址。
如果你的域名是在阿里云注册的话,可以到域名管理界面,对着域名点击解析,然后按下图的示例添加解析记录即可:
添加完解析记录后,你需要在工单里回复一下,可以直接简单评论一句Done即可。这样工作人员会去验证你添加的解析记录是否已生效,验证没有问题之后,将会在评论里告诉你申请已通过:
从评论里得知,我们现在已经有权限向s01.oss.sonatype.org这个地址发布库了。
创建密钥
MavenCentral还要求,所有发布的库都必须使用GPG来进行签名才行,所以接下来我们就进行这个操作。
GPG在一些Linux系统上是内置的,如果你使用的Linux系统没有内置的话可以通过以下命令进行安装:
代码语言:javascript复制sudo apt install gnupg
Mac系统可以借助HomeBrew进行安装,命令如下:
代码语言:javascript复制brew install gpg
Windows系统需要访问下面的地址手动下载安装:
http://www.gnupg.org/download/
安装完成之后,输入以下命令创建密钥:
代码语言:javascript复制gpg --full-generate-key
接下来会弹出一系列的选项让你选择,比如密钥的类型,密钥的长度,密钥过期时间等。如果没有什么特殊需求的话,一路点击回车,使用默认选项就好了。
除此之外,还会要求你填写姓名、邮箱等内容,以及为这个密钥设置密码。
以上内容都填写完成之后,你就可以看到你创建的密钥了:
紧接着,我们需要把刚刚创建好的密钥上传到GPG服务器。这样MavenCentral到时候可以从GPG服务器上拿到我们的密钥,从对上传的包进行验证。
上传命令如下:
代码语言:javascript复制gpg --keyserver hkp://pgp.mit.edu --send-keys C37AF927
注意,最后send-keys后面使用的密钥ID是你刚刚创建的密钥ID的最后8位。这里一定要使用最后8位,我之前因为使用了完整的密钥ID,结果一直出现奇奇怪怪的错误。
最后一步,执行以下命令生成私钥文件:
代码语言:javascript复制gpg --export-secret-keys -o 文件路径/secring.gpg
这个私钥文件一定要在你本地保存好,后面提交库的时候还需要用到它。
开始发布
以上所有步骤全部完成之后,下面就可以开始发布我们编写的开源库了。
为了让发布过程变得更加简单,我使用了gradle-maven-publish-plugin这样一个第三方开源插件。当然如果你直接使用官方的maven-publish插件也是可以实现同样的功能的,只是得额外写不少代码才行。
gradle-maven-publish-plugin插件的开源库地址是:
https://github.com/vanniktech/gradle-maven-publish-plugin
这个库的使用方法非常简单,将以下代码复制粘贴到你要发布的开源库所在模块的build.gradle文件的最底部即可:
代码语言:javascript复制...
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.17.0'
}
}
allprojects {
plugins.withId("com.vanniktech.maven.publish") {
mavenPublish {
sonatypeHost = "S01"
}
}
}
apply plugin: "com.vanniktech.maven.publish"
接来下打开项目根目录下的gradle.properties文件,并且按照下面的模板填入如下内容:
代码语言:javascript复制GROUP=com.guolindev.glance
POM_ARTIFACT_ID=glance
VERSION_NAME=1.0.0
POM_NAME=Glance
POM_DESCRIPTION=A simple and handy Android database debugging library.
POM_INCEPTION_YEAR=2020
POM_URL=https://github.com/guolindev/Glance/
POM_LICENSE_NAME=The Apache Software License, Version 2.0
POM_LICENSE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt
POM_LICENSE_DIST=repo
POM_SCM_URL=https://github.com/guolindev/Glance/
POM_SCM_CONNECTION=scm:git:git://github.com/guolindev/Glance.git
POM_SCM_DEV_CONNECTION=scm:git:ssh://github.com/guolindev/Glance.git
POM_DEVELOPER_ID=guolindev
POM_DEVELOPER_NAME=Lin Guo
POM_DEVELOPER_URL=https://github.com/guolindev/
signing.keyId=密钥ID的后8位
signing.password=密钥密码
signing.secretKeyRingFile=私钥文件路径
mavenCentralUsername=Sonatype账号
mavenCentralPassword=Sonatype密码
这个模板的前三项决定着你的开源库的包路径是什么,比如按照我上面的写法,那么这个开源库的包路径就是:
代码语言:javascript复制com.guolindev.glance:glance:1.0.0
其他几项大多是一些说明型的内容,根据自己的实际情况填写就可以了。
最后密钥部分要填写你刚才创建的公钥ID和密码,以及私钥的文件路径,另外还要填写Sonatype的账号密码。
由于我们在这个文件当中填写了很多隐私内容,一定要记得将它排除在版本控制之外。
现在,我们可以通过在Android Studio右侧工具栏的Gradle页签当中找到publish这个任务,双击执行即可将这个库发布出去。
如果一切顺利的话,就应该能在控制台中看到库已经发布成功了。
同步到MavenCentral
但是到这里还没完。
需要知道的是,我们刚才并没有将库发布到MavenCentral,MavenCentral也不允许我们直接将库发布上去。
回顾一下一开始创建的工单,工作人员回复我们的是什么?
可以看到,我们只是可以向s01.oss.sonatype.org这个地址发布库,而这并不是MavenCentral。
另外我们刚才在build.gradle文件中编写的发布脚本也证实了这一点:
代码语言:javascript复制allprojects {
plugins.withId("com.vanniktech.maven.publish") {
mavenPublish {
sonatypeHost = "S01"
}
}
}
这里将sonatypeHost指定成了S01,而S01指的就是将库发布到s01.oss.sonatype.org。
那么要如何才能将库发布到MavenCentral呢?接下来我们还需要做一下同步操作。
访问以下网址,并使用你的Sonatype账号密码登录(登录按钮在页面右上角):
https://s01.oss.sonatype.org/
登录成功之后,页面的左侧边栏当中将会多出一个Staging Repositories选项:
点击该选项,你就能看到刚刚发布成功的开源库了:
现在我们需要将这个库同步到MavenCentral仓库。操作方法是,先勾选中这个仓库,然后点击Close按钮关闭仓库,并在弹出的确认窗口中点击Confirm。
Close完毕之后,刷新界面,你会发现Release按钮就变成可点击的状态了:
点击Release按钮,并在弹出窗口中点击Confirm,这样就可以将这个开源库同步到MavenCentral上了。
不久之后,你会在之前创建的工单界面看到一条新的留言:
这是在告诉我们,同步工作已经开始了,通常大概需要30分钟左右的时间。但是如果想要在search.maven.org中可以搜到我们提交的仓库,最多可能需要4小时之久。
我并没有具体去验证一下同步到底需要多长时间,反正我是点击了Release按钮之后,第二天再到search.maven.org中去搜索,已经可以找到昨天提交的库了:
提交完成之后,想要在项目中引用这个库的话,只需要这样写即可:
代码语言:javascript复制dependencies {
implementation 'com.guolindev.glance:glance:1.0.0'
}
和之前使用JCenter仓库的写法并无差别。
到这里,我们就把将开源库发布到MavenCentral的所有流程都走了一遍。只要跟着这些流程去操作,相信大家都可以成功将库发布到MavenCentral上。
同时本篇文章又成为了《第一行代码 第3版》的又一篇DLC。伴随着Google的高速技术迭代,我已经不知道为这本书发了多少篇补丁文章了。
另外,细心的朋友可能注意到了,本文我一直在用Glance这个库进行演示,这意味着Glance的新版本很快就要发布了。那么下篇原创文章,我会跟大家聊一聊新版的Glance又多了哪些新功能,我们下期见。
如果想要学习Kotlin和最新的Android知识,可以参考我的新书 《第一行代码 第3版》,点击此处查看详情。