以往我们都使用 6.x 版本的 Gradle,在这个基础上,可以使用 maven
插件来将 jar 包发布到 Maven Central。其具体做法如下(以公司的 common-jvm 包为例):
... ...
apply plugin: 'maven'
apply plugin: 'signing'
... ...
task javadocJar(type: Jar) {
from javadoc
classifier "javadoc"
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier "sources"
}
artifacts {
archives javadocJar, sourcesJar
}
signing {
sign configurations.archives
}
... ...
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { deployment ->
signing.signPom(deployment)
}
repository(url: nexus_release_url) {
authentication(userName: nexus_username, password: nexus_password)
}
snapshotRepository(url: nexus_snapshot_url) {
authentication(userName: nexus_username, password: nexus_password)
}
pom.project {
name "common-jvm"
packaging 'jar'
description 'iSysCore Common Kotlin Library'
url 'https://github.com/isyscore/common-jvm'
scm {
connection 'https://github.com/isyscore/common-jvm'
developerConnection 'https://github.com/isyscore/common-jvm'
url 'https://github.com/isyscore/common-jvm'
}
licenses {
license {
name 'MIT License'
url 'https://github.com/isyscore/common-jvm/blob/main/LICENSE'
}
}
developers {
developer {
id 'isyscore'
name 'isyscore'
email 'hexj@isyscore.com'
}
}
}
}
}
}
虽然看起来挺麻烦的,但是也算是一劳永逸。但是当我们把 Gradle 版本升到 7.x 之后,这个发布方式就不能用了,原因是 maven 插件已被删除,而 7.x 带的插件是 maven-publish,这使得发布方式有了一个巨大的变化。
现在新的写法是这样的:
apply plugin: "java"
apply plugin: "maven-publish"
... ...
task sourcesJar(type: Jar) {
classifier = "sources"
from sourceSets.main.allJava
}
task javadocJar(type: Jar) {
classifier = "javadoc"
from javadoc.destinationDir
}
... ...
publishing {
publications {
mavenKotlin(MavenPublication) {
groupId = "com.github.isyscore"
artifactId = "common-jvm"
version = "2.0.0"
from components.java
artifact sourcesJar
artifact javadocJar
pom {
name = "common-jvm"
description = "iSysCore Common Kotlin Library"
url = "https://github.com/isyscore/common-jvm"
packaging = "jar"
licenses {
license {
name = "MIT License"
url = "https://github.com/isyscore/common-jvm/blob/main/LICENSE"
}
}
developers {
developer {
id = "isyscore"
name = "isyscore"
email = "hexj@isyscore.com"
}
}
scm {
connection = "https://github.com/isyscore/common-jvm"
developerConnection = "https://github.com/isyscore/common-jvm"
url = "https://github.com/isyscore/common-jvm"
}
}
}
}
repositories {
maven {
name = "Release"
url = "$nexus_release_url"
credentials {
username = "$nexus_username"
password = "$nexus_password"
}
}
maven {
name = "Snapshot"
url = "$nexus_snapshot_url"
credentials {
username = "$nexus_username"
password = "$nexus_password"
}
}
}
}
signing {
sign publishing.publications.mavenKotlin
}
在这里的变动中,主要是必须带入 java 插件,而之前在发布时,如果是纯粹的 Kotlin 项目,则不需要带入 java 插件。而在 Gradle 7.x 下,如果不带 java 插件,则编译后不会有任何 Kotlin 代码被编译到 jar 包内。
然后就是将 maven 插件变更为 maven-publish ,然后将原本的 uploadArchives
任务修改为 publishing
任务。
我们可以发现,新版本的写法和老版本相比,差异不大,主要都是在构建 POM 信息,唯一需要注意的,是签名的位置,Gradle 脚本是“按代码顺序执行”的,因此签名的位置在这里就比较重要,必须写在 publishing 之后。
当然了,在整个迁移的过程中,其实还是发生了不小的麻烦的,最大的困扰其实就是 Maven Central 本身,在 JCenter 跑路后(JCenter 的发布是真的简单),也只有 Maven Central 可以作为可靠的发布平台了。其中的要点有几个:
- 必须在 Sonatype 上先注册帐号,并且进行开源项目的认证(最好是Github)
- 发布时必须是固定的 IP 地址,如果整个过程中发生了 IP 地址变化,那么发布会失败(这个在家用网络中经常发生,解决方法是使用 VPN,这样你会得到一个固定的 IP)
- 耐心是必要的,因为 Maven Central 本身也非常不稳定,经常发生上传了一半服务器拒绝继续提供服务的情况,这不是你的网络问题,也不是你的 VPN 的问题,正是 Maven Central 自己的毛病。所以一次发布可能会伴随着数次的失败,只能靠耐心来解决问题了。
最后再吐个槽,这种如此难用的服务,居然能十年如一日的被用到今天,它不是早就应该被取代的么?为什么死的是 JCenter 😦