发布Maven构件到中央仓库

之前写过一篇如何使用Nexus私服,发布自己写的maven构件,供大家使用。但是只能在公司内部用, 而你想全世界的人都能用到你写的东西,就需要发布到Maven中央仓库了。

本篇文章详细讲解如何发布Maven构件到中央仓库。

注册Sonatype的账户

maven中央仓库是有一个叫做Sonatype的公司在维护的,在发布构件之前需要 注册一个账号, 记住自己的用户名和密码,以后要用。

同时,还要记住一个地址,将来在查询自己所发布构件状态和进行一些操作的时候要使用 https://oss.sonatype.org/

提交发布申请

提交申请,在这里是创建一个issue的形式,创建地址:https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

在填写issue信息的时候,有一些需要注意的地方:

  1. “group id” 就是别人在使用你的构件的时候在pom.xml里面进行定位的坐标的一部分,最好是自己的域名倒序, 如果自己没有域名就填写github域名,比如io.github.yidao620c
  2. “project url”是这个项目站点,填写你的github项目地址即可。
  3. “SCM url”这个是构件的源代码URL,一般就是可以通过git clone命令来下载源码的地址, 比如我的是 https://github.com/yidao620c/springfox-swagger-ui.git

其他的就没有什么了,提交之后就等工作人员离开确认吧。有时候你填写的是自己域名的时候,工作人员会问你是不是真的是自己的域名, 你在下面回答他就可以了。

过段时间就去看看你的issue,如果工作人员回复你说”Configuration has been prepared…”,如下:

那么你就可以开始下一步了。

GPG签名

在上传构件之前,需要准备GPG以便对发布的文件进行签名。

windows用户到 http://www.gpg4win.org/download.html 去下载Gpg4win-Vanilla版来使用,linux的直接安装gpg软件包就行。

下载之后执行:

1
gpg --gen-key

需要输入姓名、邮箱等字段,其它字段可使用默认值,此外,还需要输入一个 Passphase,相当于一个密钥库的密码, 一定不要忘了,也不要告诉别人,最好记下来,因为后面会用到。

配置settings.xml

找你所使用的maven的配置文件<mvn_home>/conf/settings.xml,在配置文件中找到节点, 这个节点默认是注释了的,我们就在这个猪似的外边增加一个的配置如下:

1
2
3
4
5
6
7
<servers>
<server>
<id>oss</id>
<username>用户名</username>
<password>密码</password>
</server>
</servers>

这里的id是将来要在pom.xml里面使用的,所以务必记好,用户名和密码就是在Sonatype上面注册的用户名和密码。

配置pom.xml

接下来就是重头戏了,pom.xml是一个maven项目的重点配置,一个项目的所有配置都可以由这个文件来描述, 文件中的所有配置都有默认值,也就是说所有的配置都是可选配置,但是为了把构件发布到中央仓库, 我们必须配置一些关键信息,否则再发布时是不会通过了。

这些必须明确的信息包括:name、description、url、licenses、developers、scm等基本信息, 此外,使用了 Maven 的 profile 功能,只有在 release 的时候,创建源码包、创建文档包、使用 GPG 进行数字签名。 此外,snapshotRepository 与 repository 中的 id 一定要与 settings.xml 中 server 的 id 保持一致。

下面是我的一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.xncoding</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
<packaging>jar</packaging>

<name>springfox-swagger-ui</name>
<description>swagger-ui for xncoding</description>
<url>https://www.xncoding.com/</url>

<licenses>
<license>
<name>The MIT License (MIT)</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>

<developers>
<developer>
<name>yidao620c</name>
<email>yidao620@gmail.com</email>
</developer>
</developers>

<scm>
<connection>scm:git:git@github.com:yidao620c/springfox-swagger-ui.git</connection>
<developerConnection>scm:git:git@github.com:yidao620c/springfox-swagger-ui.git</developerConnection>
<url>https://github.com/yidao620c/springfox-swagger-ui</url>
</scm>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
</dependencies>

...其他省略...

<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<!-- Source -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Javadoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- GPG -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>oss</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>oss</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</profile>
</profiles>
</project>

上传构件

待构件编写完成,就可以进行上传、发布了。在命令行进入项目pom.xml所在路径,执行:

1
mvn clean deploy -P release

在稍后些时候会要你输入gpg密钥库的密码,输入即可完成上传。 当然有时候不会弹出输入密码的输入框,只是提示需要输入密码,根据gpg插件的官网解释,需要加上密码作为参数执行命令,即:

1
mvn clean deploy -P release -Dgpg.passphrase=密码

在OSS中发布构件

构建上传之后需要在OSS系统中对操作进行确认,将构件发布,进入 https://oss.sonatype.org/ 使用你的用户名和密码登陆之后, 在左边菜单找到“Staging Repositories”,点击,在右边上面一点有一个输入搜索框输入你的groupid进行快速定位, 可以发现这时你的构件状态是“open”,勾选你的构件,查看校验的结果信息, 如果没有错误就可以点击刚才勾选的checkbox上面右边一点的“close”按钮,在弹出框中“confirm”,这里又需要校验一次,稍后结果会通过邮箱通知。

我再close过程中出现过验证签名失败的问题:

1
No public key: Key with id: (xxxx) was not able to be located on http://keyserver.ubuntu.com:11371

只需要在本地执行:

1
gpg --keyserver hkp://keyserver.ubuntu.com --send-keys xxxx

其中的xxxx是你的GPG key,在生成GPG密钥的时候控制台会打印。

发送key完成后再次试一下close成功了。刷新页面,这是状态已经是“closed”的了,再次勾选,然后点击“close”旁边的“release”, 在弹出框中进行“confirm”,稍后结果会通过邮件进行通知。

注意,你执行release成功之后,OSS里面就没有这个构件了,我一开始还在想这家伙跑哪去了,原来是跑到Maven中央库里面去啦。

通知sonatype的工作人员关闭issue

回到issue系统,找到你的那个申请发布构件的issue,在下面回复工作人员,说明构件已经发布,待工作人员确认后,会关闭这个issue。

使用构件

一切完成后并不可以马上就使用你所发布的构件,得等系统将你的构件同步到中央仓库之后才可以使用, 这个时间至少要2个小时,然后就可以在中央仓库的搜索页面 http://search.maven.org/ 搜到你的构件啦,

赶快截图,向他人炫耀一下吧。

下次再发布

你看了上面这长篇大论,感觉好像流程很复杂。但是好消息是你只需要第一次的时候这么做。后面再发布就轻松多啦。

第一次成功之后,以后就可以使用你的groupid发布任何的构件了,只需要你的groupid没有变就行,(当然不能发布重复构件哈),不用这么麻烦。

以后的发布流程:

  1. 构件准备好之后,在命令行上传构建;
  2. 登录 https://oss.sonatype.org/ , close 并 release 构件;
  3. 等待同步好(大约2小时多)之后,就可以使用了