问题描述

有个多嘴的同事,开会时多了一嘴:要不要把我们的项目推送到中央仓库管理起来(我们项目是在gitHub开源的);然后领导同意了,本来事情落他身上了,但奈何他身上任务太多,最后这活还是分配到我身上了,提前说一声,我对这里的操作,所知=0;但还好有百度,只能做起来;

这里参考了好多个博主的文章,偷偷把一个写的比较清晰完善的拿过来一下,嘿嘿,最后会挂上此博主文章的链接;随后我也会补充上自己遇到的恶心问题

发送流程

0.先来说一下首次上传的核心步骤,由于步骤中的过程相对较复杂,所以先抽象下基本思路,再展开讲解,避免大家看不懂.

抽象步骤:

  • 注册账号
  • 提交工单
  • 人工审核及确认
  • 上传SNAPSHOT版本
  • 上传release版本

画了张流程图,过程大致如下:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_中央仓库地址 查找jar包有哪些版本


jar包是不能直接发布到中央仓库的,只能先推到第三方,然后第三方检验jar包没问题了,才能通过第三方发送到远程仓库

具体发布流程操作

1.注册sonatype账号

Sign up for Jira - Sonatype JIRA

密码要求比较高,大小写数字符号啥的都要有,所以务必要记住此密码,记不住的事先保存好,后面要经常用到账号和密码.

2.创建Issue

用上面创建的账号密码登录后,点击页面上方导航栏的Create按钮创建Issue:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_jar_02


中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_java_03


通过以上两个步骤,你的工单就被创建完成了,接下来就耐心等待工作人员审核,由于美国和中国的时差,所以基本上大部分时候回复你都是23:00以后,注意留意你注册账号时填写的邮箱,回复内容会在邮箱里通知你.(我是工作日下午申请的,我申请了2次,一般在20分钟内就回复了)

3.确认邮件

在收到工作人员的确认邮件后,在邮件内容中他们通常会要求验证你填写的groupId中的域名或github账户是不是你本人的

  • 如果你填写的是域名,他们会要去你用该域名的邮箱给他们发一封邮件进行确认
  • 如果你填写的是github账户,他们会要求你在你的github中创建一个指定名称的仓库进行验证(如下图,按要求去创建即可)

    这里多说一句,我申请了2次,一次使用github作为groupId,一次是用我们的官网作为groupId,但用官网作为groupId时,还需要添加一个什么DNS TXT文件(如下图),我对域名这方面的知识不太了解,而且我们部门往中央仓库推jar包的也少之又少,所以最后使用的io.github.XXX作为的groupId;只需要在自己的gitHub仓库,按他的要求创建一个名字为OSSRH-85817的仓库就可以了(每个人的编号不一样,需要看邮箱中的名字,这个仓库没什么用,只是为了验证下这个gitHub仓库是你所属,验证完毕后就可以删除,我这里也没有gitHub仓库的权限,是让领导创建了仓库)

    创建完以后,点击页面的Respond按钮,重新提交即可

    过一会刷新状态为 已解决 就已经创建完成了, 刚刚创建的临时仓库可以删除
4.上传至中央仓库

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_xml_04

4.1上传SNAPSHOT的步骤

如果步骤走不下去,请务必查阅官方文档,以官方文档为准,因为可能会有更新
参考文档地址:OSSRH Guide - The Central Repository Documentation ,然后点击页面的Apache Maven按钮,里面就是要配置的内容(maven的setting.xml文件和项目的pom依赖)

流程:配置秘钥->配置settings.xml->配置pom.xml->上传

1. 配置秘钥:

下载并安装GPG:

https://www.gnupg.org/download/index.html 根据你电脑当前系统选择合适的安装包下载并安装,安装按默认勾选的配置一路安装即可.
生成秘钥有两种方式,敲命令和UI界面两种,这里仅演示通过命令创建的方式

生成秘钥:
 
gpg --gen-key
 Real name: 名字(E文)
 Email address: 邮箱(自己的邮箱,我记得这个邮箱是要接收邮件,做验证用的,千万别瞎填一个不能用的邮箱)
 You selected this USER-ID:
 "xxx[xxx@qq.com](mailto:xxx@qq.com)"
 Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
 之后往下,会让你输入用户名和邮箱,还有一个Passphase(输入两次,务必牢记,建议先找个地方记下来,后续要用到)
查看公钥
C:\Users\86151>gpg --list-key

查询结果:
C:\Users\86151\AppData\Roaming\gnupg\pubring.kbx
------------------------------------------------
pub   ed25519 2022-11-02 [SC] [expires: 2024-11-01]
      A66E2623D457CA43088FE730892152C51A188059
uid           [ultimate] lei_1997 <2987866881@qq.com>
sub   cv25519 2022-11-02 [E] [expires: 2024-11-01]
其中A66E2623D457CA43088FE730892152C51A188059就是你的公钥key

可能安装GPG也会安装一个可视化页面,此时可视化页面的证书下就会有你刚生成的公钥key,但注意,可视化页面上显示的秘钥并不完整,只是后16位,不要以为是秘钥不对,如下图

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_java_05

发布公钥:
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys A66E2623D457CA43088FE730892152C51A188059
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys A66E2623D457CA43088FE730892152C51A188059
 
成功的话会有如下结果
gpg: key 892152C51A188059: "lei_1997 <2987866881@qq.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

为什么要发布公钥呢,因为往第三方库去推jar包时,需要秘钥,而且只能发布到第三方允许的地址

2. 配置settings.xml

找到你IDEA自带或者你安装的Maven所在的目录:
File->settings->Build->Maven->MavenHomePath,进入此目录在conf文件夹下就可以看到settings.xml文件,如果没有的话可以自己新建一个.

setting.xml中配置如下:

<servers>
	  <server>
        <id>ossrh</id>
        <username>第一步SonaType账号</username>
        <password>填你注册SonaType时填写的密码</password>
	  </server>
  </servers>

<-- 这个配置,是为了执行 mvn clean deploy 过程中,让你输入一次Passphase的操作,
如果在这里配置了,估计在执行mvn clean deploy 中就不用输入了,我这里没有配置,在mvn clean deploy输了一次Passphase,大家根据自己情况决定是否添加,
个人觉得还是不要添加吧,就在mvn clean deploy中输入一次密码而已,万一加上再报了什么不可知的错误了呢  !-->
<profiles>
    <profile>
      <id>ossrh</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <!--这里填你安装的GnuPG位置-->
        <gpg.executable>E:\GnuPG\bin\gpg.exe</gpg.executable>
        <gpg.passphrase>填写你生成秘钥时输入的Passphase</gpg.passphrase>
        <!--这里填你秘钥在磁盘上的位置,可通过上面步骤的 gpg --list-keys找到-->
        <gpg.homedir>C:\Users\86151\AppData\Roaming\gnupg\</gpg.homedir>
      </properties>
    </profile>
  </profiles>
3. 配置Pom.xml

因为我们的项目是父项目下有多个子项目,我们现在只是发布其中一个子项目,所以在子项目的pom.xml中配置的以下内容
注意:如果要发布的子项目中,引了其他子项目,是不能发布的,除非引的这个子项目已经发布到中央仓库了;换句话说,项目中的dependency都得是在中央仓库能找到的

<groupId>io.github.cas-bigdatalab</groupId>
<artifactId>piflow-core</artifactId>
<!--需要特别注意,你上传的是SNAPSHOT仓库,所以此处版本号后缀必须带SNAPSHOT-->
<version>0.9-SNAPSHOT</version>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<!--项目信息...-->
<name>piflow-core</name>
<description>Test upload minimum version</description>
<url>https://github.com/cas-bigdatalab/piflow</url>


<!--开源协议...-->
<licenses>
    <license>
        <name>The Apache Software License, Version 2.0</name>
        <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
    </license>
</licenses>

 <!--开发者信息-->
<developers>
    <developer>
        <id>piflow</id>
        <name>piflow-core</name>
        <email>填写一个开发者的email就行,没多大用</email>
        <roles>
            <role>admin</role>
        </roles>
        <timezone>+8</timezone>
    </developer>
</developers>

<!--项目的一些依赖,如果项目有其他的依赖,不要删-->
<dependencies>
   <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>net.liftweb</groupId>
        <artifactId>lift-json_2.11</artifactId>
        <version>2.6.1</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
</dependencies>

<distributionManagement>
	<!--注意,此id必须与setting.xml中指定的一致-->
	<repository>
		<id>ossrh</id>
		<!--如果是要推到自己的私服,这里地址应该改为自己私服的地址?具体的可以在百度百度-->
		<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
	</repository>
	<snapshotRepository>
		<id>ossrh</id>
		<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
	</snapshotRepository>
</distributionManagement>

<profiles>
    <profile>
        <!--注意,此id必须与setting.xml中指定的一致,不要自作聪明改它名字-->
        <id>ossrh</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <plugins>
            	<!--发布到中央SNAPSHOT仓库插件-->
                <plugin>
                    <groupId>org.sonatype.plugins</groupId>
                    <artifactId>nexus-staging-maven-plugin</artifactId>
                    <version>1.6.7</version>
                    <extensions>true</extensions>
                    <configuration>
                        <serverId>ossrh</serverId>
                        <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
                        <autoReleaseAfterClose>true</autoReleaseAfterClose>
                    </configuration>
                </plugin>

                <!--生成源码插件-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>2.2.1</version>
                    <executions>
                        <execution>
                            <id>attach-sources</id>
                            <goals>
                                <goal>jar-no-fork</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <!--生成API文档插件-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <version>2.9.1</version>
                    <executions>
                        <execution>
                            <id>attach-javadocs</id>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <!--gpg插件-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-gpg-plugin</artifactId>
                    <version>1.5</version>
                    <executions>
                        <execution>
                            <id>sign-artifacts</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>sign</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.3.1</version>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

以上配置,都不可缺少,我之前少写了一个developers,虽然打包没问题,但最后提交到第三方时,检测有问题,可以参考上面挂的链接从文档中粘贴过来就行,这里再写一次链接 完成上述配置,你已经基本上走完了80%的步骤了,此时,你可以通过Maven尝试打包一下你的项目,期间可能会出现弹窗让你填一次Passphase

但同时坑也来了,这个坑曾浪费了我两天时间,其实也不是很大的问题,这里大家留意一下:因为大多数人,安装maven时都不会把maven安装到默认位置(C盘),但这里我无论是用idea的插件打包还是mvn命令打包,都会报401错误,如下图:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_中央仓库地址 查找jar包有哪些版本_06


其实401错误,大部分就是权限问题,奈何第一次发布jar包到远程仓库,根本无从排查问题;然后百度上说的百分之98的解决方案都是在maven的setting.xml文件中添加配置:

<server>
	<id>releases</id>
	<username>SonaType账号</username>
	<password>SonaType密码</password>
</server>
<server>
	<id>snapshots</id>
	<username>SonaType账号</username>
	<password>SonaType密码</password>
</server>

<!--那对应的pom中的配置的id也要改-->
<distributionManagement>
	<repository>
		<id>releases</id> <!--改成和setting文件中的id一致-->
		<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
	</repository>
	<snapshotRepository>
		<id>snapshots</id> <!--改成和setting文件中的id一致-->
		<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
	</snapshotRepository>
</distributionManagement>

但这种方法我尝试了,还是报401错误,并没有解决;所以这种解决方法就是胡扯(我尝试的记得把setting新加的配置去掉,还有pom中的id也还改回来)

最后卡了2天,无意中看到了一个解决方案,最后也成功解决了我报的401错误,如下:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_jar_07


所以这里要把setting.xml,复制一份到C盘的.m2文件夹下(我是windows环境),然后再执行mvn clean deploy命令;就成功了;如下:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_java_08


至此,SNAPSHOT版本已被上传至中央SNAPSHOT仓库,可以在浏览器访问Nexus Repository Manager,登录后查看结果如下图:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_xml_09

4.2 上传release版本

整体流程和上传SNAPSHOT版本一致,下面仅贴出差异点:

1.settings.xml
<!--将原来server标签和profile标签中的的ossrh替换为release-->
<id>release</id>
<servers>
  <server>
       <!--<id>ossrh</id>-->
       <id>release</id>
       <username>第一步SonaType账号</username>
       <password>填你注册SonaType时填写的密码</password>
  </server>
 </servers>
2. pom.xml
<!--修改GAV中的版本号,把SNAPSHOT后缀去掉-->
<version>0.9</version>

<!--将原来server标签和profile标签中的的ossrh替换为release-->
<id>release</id>

<!--移除此发布到中央SNAPSHOT仓库插件,并替换为下面的发布到中央release仓库的插件-->
<!--
<plugin>
     <groupId>org.sonatype.plugins</groupId>
     <artifactId>nexus-staging-maven-plugin</artifactId>
     <version>1.6.7</version>
     <extensions>true</extensions>
     <configuration>
         <serverId>ossrh</serverId>
         <nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
         <autoReleaseAfterClose>true</autoReleaseAfterClose>
     </configuration>
 </plugin>
-->

<!--发布到中央release仓库插件-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.5.3</version>
    <configuration>
        <autoVersionSubmodules>true</autoVersionSubmodules>
        <useReleaseProfile>false</useReleaseProfile>
        <releaseProfiles>release</releaseProfiles>
        <goals>deploy</goals>
    </configuration>
</plugin>

然后执行mvn clean deploy命令即可;然后会接收到系统发的邮件:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_maven_10

在完成了SNAPSHOT和release版本上传之后,你会收到系统发来的邮件
至此,恭喜你已首次完成将项目发布至中央仓库.

5.后续

在之后,随着你项目的迭代,你可能需要发布新的版本至中央仓库,此时你可以跳过上传SNAPSHOT,直接上传release版本至中央仓库,由于非首次发布,他们的机器人也不再会帮助你自动同步了,此过程需要你手动触发,在上传完release包之后,打开官方页面,进入操作,具体流程如下图:

中央仓库地址 查找jar包有哪些版本 上传jar到中央仓库_jar_11


这里大家要留意一下,仔细看上面的步骤,点完 close后,等待几十秒(我是等了2分钟),就可以点击Refresh按钮了,别傻傻的等着close结束,我第一次没仔细看步骤,下午4点点了close,下班还没结束,然后电脑没关机,第二天上班还没结束!!! 所以自己点Refresh,而且刷新后才可以看close过程中是否发生错误,如果有错误,根据错误提示去修改即可(我曾就在pom中少写了developers信息,在这里报错了,然后点击Drop删除包,在pom中补充了developers信息,重新上传,close后点击Refresh就没再出现报错信息)

点完Release就同步到中央仓库了,但看其他的博主说不会立刻在[中央仓库](https://mvnrepository.com/)搜到,会有个时间差,具体时间差是多少,我给忘了

以上内容均是参考这个博主的文章写的,我另加了一点补充,算是有些抄袭吧


总结

由于是第一次搞这个东西,期间虽然跟着百度和视频做的,但由于401错误让我怀疑是不是哪一步做错了,期间我还秘钥卸载重新弄了2次;但好在最后成功解决了问题,我最后虽然没发布到中央仓库,其实close没问题,点击一下Release按钮就发布到中央仓库了,但因为我这里groupId是用的io.github.XXX,我们是要用域名的,但域名问题还没搞定,毕竟一旦上传到中央仓库,就没有权限去操作这个jar包了,所以我没走最后一步