将java项目发布到maven中央仓库(踩坑大全)

前言:

第一次将构件发布到中央仓库,真的不是一件轻松的事情,网络上有很多其他文章大都不会把坑帮你描述清楚。所以觉得非常有必要把些步骤记下来,让大家少走点弯路。

一、maven中央仓库简介

相关内容介绍
maven
Sonatype中央仓库官网:http://www.sonatype.org/

二、发布的前置工作

2.1注册账户

注册地址:https://issues.sonatype.org/secure/Signup!default.jspa

坑: 注册时Username 一定不要使用中文。老外对中文支持不好。后续一堆问题,还要重建账户。

注册完登陆,地址:https://issues.sonatype.org/login.jsp

2.2 创建一个 Issue

创建地址:https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

坑1: 通过控制面板上的创建按钮创建记得选择类别:
Community Support - Open Source Project Repository Hosting

坑2:group Id:这个必须要注意,如果你用的是GitHub, 一定要是 com.github.你的github用户名, 
例如项目地址是: https://github.com/xxx/Common, 那groupId就是 com.github.xxx

如果你有自己的域名和项目地址也可以,官方人员会询问你是否有这个域名的所有权。

在你项目的pom里一定要使用这个groupId,

如果是自定义域名,必须添加域名解析如下图所示,以下是我使用自定义域名后的官方回复。
在这里插入图片描述

2.3 使用 GPG 生成密钥对

在等待Issue的时候可以先把密钥搞好

2.3.1 GPG是什么?

说明文档:http://central.sonatype.org/pages/working-with-pgp-signatures.html

大体是说,部署组件到中央仓库要求需要GPG签名文件,而GnuPG 或者 GPG 是OpenPGP标准的一个实现,能够管理签名相关的东西,然后这个文档将告诉你如何生成自己的签名Key Pair 密钥对以及分发到 key server 以便别人可以验证签名(最后其实就是在发布的时候,Sonatype会通过key server上的信息进行验证deploy文件的有效性)

2.3.2 安装 GnuPG

下载地址 :https://www.gnupg.org/download/


Windows 系统,直接下载 Gpg4win。

坑:下载的时候有个坑,会弹出一个捐助页面,然后没有下载的地方,也没有自动开始下载.
感觉好像不捐助就不能下载一样.其实在下载页面下面有个All Downloads,
里面有个连接 files.gpg4win.org,在这里找到与下载页面上的最新版相同的版本号下载即可

安装过程中在选择组件的时候,除了默认必须安装的,其他取消即可

安装完成后,打开CMD 执行 gpg --version 验证安装是否成

2.3.3 生成密钥对
gpg --gen-key
Real name: 输入名字(注意不要用中文)
Email address: 邮箱
You selected this USER-ID:
"xxxxxx@qq.com"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? o

之后往下,会让你输入Passphase(输入两次),相当于密钥库密码,不要忘记。

2.3.4 查看公钥
gpg --list-keys
#其中,pub表示是公钥,而sub表示私钥。 

记住pub

2.3.5 将公钥发布到 PGP 密钥服务器
gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 你的公钥指纹 #即pub   

这里可能是传输的原因要稍等,或者你也可以执行两次。

2.3.6 查询公钥是否发布成功
gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 你的公钥指纹 #即pub   
以下注意:
坑: 一般网上的文档就说明这样发布就可以了实际上,后面部署会报错,错误如下截图。

failureMessage No public key: Key with id: (1fcda02dd63733fe) was not ableto be located on http://pgp.mit.edu:11371/. Uploadyour public key and try the operation again.
failureMessage No public key: Key with id: (1fcda02dd63733fe) was not ableto be located on http://keyserver.ubuntu.com:11371/.Upload your public key and try the operation again.
failureMessage No public key: Key with id: (1fcda02dd63733fe) was not ableto be located on http://pool.sks-keyservers.net:11371/.Upload your public key and try the operation again.

从上面我们发现有三个 key-servers 是 Sonatype公司要用到的,Sonatype公司会在上面任意一个key-servers上进行搜索公钥,具体的key-servers 为:
http://pgp.mit.edu:11371
http://keyserver.ubuntu.com:11371
http://pool.sks-keyservers.net:11371

这个要注意了,这个是带端口的,这个我在实际操作中,也踩了这个坑,一开始我上传公钥到下面中的一个(注意,没有带端口号)

gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 你的公钥指纹
gpg --keyserver hkp://pgp.mit.edu --send-keys 你的公钥指纹
gpg --keyserver hkp://keyserver.ubuntu.com --send-keys 你的公钥指纹

注意了,协议不是http,而是 hkp,要看清楚了,实际上是需要带端口号上传的:

gpg --keyserver hkp://pool.sks-keyservers.net:11371 --send-keys 你的公钥指纹
gpg --keyserver hkp://pgp.mit.edu:11371 --send-keys 你的公钥指纹
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys 你的公钥指纹

没有成功的话要注意Sonatype反馈了什么信息然后根据信息进行修改。

上面是将公钥发布到 GPG key-servers 的命令,我们可以通过以下命令查看具体的公钥信息:

gpg --keyserver hkp://pool.sks-keyservers.net:11371 --recv-keys 你的公钥指纹
gpg --keyserver hkp://pgp.mit.edu:11371 --recv-keys 你的公钥指纹
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys 你的公钥指纹

三、发布maven工程到中央仓库

3.1 Issue通过

官方会回复你,如下图所示。你就可以发布项目的
在这里插入图片描述

3.2 修改maven配置

修改maven全局配制文件 settings.xml,在maven安装目录的conf文件夹下。注意用户名密码即你注册jira账户的用户名和密码

<servers>
    <server>
        <id>oss</id>
        <username>用户名</username>
        <password>密码</password>
    </server>
</servers>
坑:通过mvn --version 查看你本机的maven安装目录。而非idea自带maven,否则一会儿执行发布命令可能会报错。
3.2 修改pom文件

添加如下信息:

<project>
    ...
    <name>Common</name>
    <description>Common is a rapid development kit.</description>
    <url>http://www.example.com/</url>
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</naurl
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>
    <developers>
        <developer>
            <name>username</name>
            <email>email@foxmail.com</email>
        </developer>
    </developers>
    <scm>
        <connection>scm:git:git@github.com:xxx/yyy.git</connection>
        <developerConnection>scm:git:git@github.com:xxx/yyy.git</developerConnection>
        <url>git@github.com:xxx/yyy.git</url>
    </scm>
    
    <profiles>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <!-- Source -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                        <version>2.2.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.9.1</version>
                        <configuration>
                            <show>private</show>
                            <nohelp>true</nohelp>
                                    <charset>UTF-8</charset>
                <encoding>UTF-8</encoding>
                <docencoding>UTF-8</docencoding>
                <additionalparam>-Xdoclint:none</additionalparam>  <!-- TODO 临时解决不规范的javadoc生成报错,后面要规范化后把这行去掉 -->
            </configuration>
                        <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 中必须包括:name、description、url、licenses、developers、scm 等基本信息,使用了 Maven 的 profile 功能,只有在 release 的时候才创建源码包、文档包、使用 GPG 进行数字签名。

这里着重介绍一下scm 参考了(https://blog.csdn.net/xiajiqiu/article/details/77607492

3.2.1Subversion on your own server:
<scm>
  <connection>scm:svn:http://subversion.example.com/svn/project/trunk/</connection>
  <developerConnection>scm:svn:https://subversion.example.com/svn/project/trunk/</developerConnection>
  <url>http://subversion.example.com/svn/project/trunk/</url>
</scm>
3.2.2 Git hosted on GitHub:
<scm>
  <connection>scm:git:git://github.com/xxx/yyy.git</connection>
  <developerConnection>scm:git:ssh://github.com:xxx/yyy.git</developerConnection>
  <url>http://github.com/simpligility/xxx/tree/master</url>
</scm>
3.2.3 Git hosted on Gitee:
<scm>
     <tag>master</tag>
     <url>https://gitee.com/xxx/yyy.git</url>
     <connection>scm:git:git@gitee.com/xxx/yyy.git</connection>
     <developerConnection>scm:git:git@gitee.com/xxx/yyy.git</developerConnection>
</scm>
3.2.4 Git hosted on BitBucket:
<scm>
  <connection>scm:git:git://bitbucket.org/simpligility/ossrh-pipeline-demo.git</connection>
  <developerConnection>scm:git:ssh://bitbucket.org:simpligility/ossrh-pipeline-demo.git</developerConnection>
  <url>https://bitbucket.org/simpligility/ossrh-pipeline-demo/src</url>
</scm>
3.2.5 Mercurial on BitBucket:
<scm>
  <connection>scm:git:git://bitbucket.org/simpligility/ossrh-pipeline-demo.git</connection>
  <developerConnection>scm:git:ssh://bitbucket.org:simpligility/ossrh-pipeline-demo.git</developerConnection>
  <url>https://bitbucket.org/simpligility/ossrh-pipeline-demo/src</url>
</scm>
3.2.6 Git on Apache Git Server from Apache Maven:
<scm>
  <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
  <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
  <url>https://github.com/apache/maven/tree/${project.scm.tag}</url>
  <tag>master</tag>
</scm>

此外,snapshotRepository 与 repository 中的 id 一定要与 setting.xml 中 server 的 id 保持一致。
如果是多模块项目的话,只需要在父 pom.xml 中声明这些,子 pom.xml 中只需要修改相应的一些信息,如 name 标签。
由于我使用的是jdk8,对doc的格式要求更严,不标准的doc注释会报错,这时候可以通过在doc插件中配制additionalparam参数,上面代码里已经配过了.但这只是临时解决方案,还是尽量使用标准的doc注释吧.

坑:在这里maven-gpg-plugin 可能标红,通过 
mvn dependency:get -DrepoUrl=http://repo.maven.apache.org/maven2/ -Dartifact=org.apache.maven.plugins:maven-gpg-plugin:1.6
手动下载,还是标红。直接忽略。不影响执行上传命令。
3.3 执行上传命令
#发布前检查version 是否已经修改成release版本。
mvn clean deploy -P release

当执行以上 Maven 命令时,会自动弹出一个对话框,需要输入上面提到的 Passphase,它就是刚才设置的 GPG 密钥库的密码。
注意:此时上传的构件并未正式发布到中央仓库中,只是部署到 OSS 中了,下面才是真正的发布。

如果发布报401错误,请再次检查 snapshotRepository 与 repository 中的 id 一定要与 setting.xml 中 server 的 id 保持一致。

四、在中央仓库发布

4.1 提交审核

使用 Jira 账号登录 https://oss.sonatype.org。注意这里的issue的网址不同。
登陆以后在控制面板的Staging Repositories 可以查看到刚提交的内容。

4.2 执行close

点击【Close】按钮,然后等待,时不时你电机系【Refresh】按钮,会把进度显示在下面的【Activity】

我们可以对比Avtivity执行Close以后成功或者失败的信息。如图4.2和4.3所示:
4.2
点开错误信息我们可以查看到错误详情。按照错误提示我们修正好重新提交再执行Close。直到成功。
错误提示
4.3

4.3 如果Close校验完成。则按钮Release可用,执行它。

这里Release不代表你已经提交到中央仓库了。而是提交到sonatype了。需要在issue添加备注提醒官方审核。如下图 我简单写了。Component has been successfully issued。
在这里插入图片描述

4.4 耐心等待官方审核。

审核成功会收到回复。例如:

什么意思呢?意思就是说10分钟内,别人就可以直接通过在pom中引入你的项目并下载依赖了,但是如果要在http://search.maven.org/ 上搜索到你的组件,还需要等待至少两个小时,因为http://search.maven.org/ 是两个小时刷新一次索引的。

我们可以maven中央仓库中查看自己的组件了:
https://repo1.maven.org/maven2/你的groupId将.变成目录分隔符/artifactId
至此,我们就完成了组件的发布了。

4.5 迭代版本的发布。

第一次发布比较麻烦,后续因为代码更新版本迭代。只需重复 3.3~4.3步骤即可。

五、使用Nexus Staging Maven plugin

简介

在Close & Release 文档中(
http://central.sonatype.org/pages/releasing-the-deployment.html#close-and-drop-or-release-your-staging-repository
),最后面有一段话:

Note thatdeploying with the Nexus Staging Maven plugin or Ant tasks will, by default,automatically attempt to close the staging repository upon deployment and canbe used to release the staging repository from the command line as well. Thisallows you to avoid logging into the OSSRH user interface altogether. Moredetails can be found in the Maven and Ant sections of this guide.

翻译一下,大概意思就说:你可以使用 Nexus Staging Maven 插件来进行你的组件发布,这样就不需要登录 OSSRH 进行界面操作了,减少了发布的复杂度。

注: OSSRH实际上就是https://oss.sonatype.org/

使用该插件发布

文档地址:http://central.sonatype.org/pages/apache-maven.html#nexus-staging-maven-plugin-for-deployment-and-release
标题很明显,就是说你可以使用 Nexus Staging 的Maven 插件实现组件的deploy和release,这样你就不需要去登录 OSSRH 网站点击Close,点击Release了。

使用很简单,在你项目的 POM中加入:

<!-- Nexus Staging Plugin, auto deploy close and release -->
<plugin>
  <groupId>org.sonatype.plugins</groupId>
  <artifactId>nexus-staging-maven-plugin</artifactId>
  <version>1.6.8</version>
  <extensions>true</extensions>
  <configuration>
     #之前步骤settings.xml中的servers中设置了这个ID
     <serverId>oss</serverId>
     #https://oss.sonatype.org/
     <nexusUrl>https://oss.sonatype.org/</nexusUrl>
     #在Staging关闭后是否自动Release,如不是自动,就需要手动,
     #你可以登录OSSRH去手动点击Release也可以自己本地执行命令:
	 #mvn nexus-staging:release
	 #当然也可以删除:
	 #mvn nexus-staging:drop 
     <autoReleaseAfterClose>true</autoReleaseAfterClose>
  </configuration>
</plugin>

发布命令和原来一样:

mvn clean deploy –P release –Dgpg.passphrse=xxxxx #xxx是你的密钥对的密码
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值