发布项目到Maven中央库

前言

此次将自己的项目推送到Maven中央库的经历简直惨不忍睹,俗话说,凡事都有第一次,越是惨痛的经验就越是印象深刻,但还是怕以后会忘记某些步骤,所以还是记录一下,供自己也供大家参考参考。

首先,我诉苦一下,网上的各种文章我基本都翻了个遍,百度/Google出来的大流程基本都一样,就像是同一个模子里刻出来的一样,但整体过程是没问题的,一步一步照着来就行了,最值得一提的是在我们操作过程中出现的各种各样的奇葩问题,这个东西只有在实际操作中才会出现的问题就很难搜到有效的解决方案了,因操作而异出现的问题也各有不同,加上身边的小伙伴对这个了解也是甚少,就算有那么一两个曾经弄过这个也没几个人有这方面详细的记录过程,所以就算他们凭借着模糊的记忆告诉了你一些经验,但也提供不了什么实质性的帮助,还是只有靠自己慢慢摸索前行,而我自己在经历了差不多快一周挠破脑袋的各种百度/Google下终于有所进展,皇天不负有心人,最后成功将项目上传至Maven中央库,可以正常使用也可以正常后续维护,想想过程虽苦但结果是欣慰的。

好了,这里说一下实际操作,文中可能 废话 比较多,如果阅读文章的同学耐心不强,认为咱很罗嗦,对你没什么用,认为多此一举,那要么请您点击上面那个耀眼的关闭按钮再去找其他文章参考吧,否则请您耐着性子慢慢看完它,当然您也可以选择性查看,如果到最后您还是认为这篇文章对您没有任何帮助,那对不起,是在下错了,告辞 o(︶︿︶)o

1、代码托管

这一步有多重要我就不在这里赘述了,将你认为可以发布的项目托管到 github/gitee 上,如果你已经完成了这个步骤当然很好,但如果还有没有完成这个步骤甚至不了解代码托管平台的同学,请自行百度/Google相关操作,如果说作为一个合格的所谓的 程序猿,你甚至都没有使用全球最有名的 “同性” 交友网站的话,你就真的有点Out了,废话不多说,这步你自己掂量着来。。。

完成你的代码托管之后,记录下你的项目地址( https://github.com/tangxbai/mybatis-mapper.git )后面需要用到。

2、需要一个 Sonatype 账号

当然,Maven中央库也不是你想发什么就发生么的,必须有人维护有人审核,有人同意你这么干你才能发布自己的应用。 https://issues.sonatype.org 这个网站就是问题管理系统,和我们平时用的 JIRA 系统类似,流程无异,只不过工作人员是美国的同学。

小提示:审核过程是由美国那边的同学完成的,因时区差异,中国和美国时间相差大概12小时,如果你在白天提交操作的话,美国那边是应该是夜晚早就下班了,所以你提交审核的时间看准时机,或者提交之后慢慢等待也行,时机恰当的话一两个小时之内就会完成审核,最长不会超过一个工作日。回复记得使用英文,因为谁也不确定别人是否能看得懂中文。

1、注册账号(已经有账号的同学相信你也已经轻车熟路了,略过吧)

去官网注册一个账号,怎么注册这种问题我就不用说了吧,注册成功后登录可以点击 头像/用户信息/参数配置 设置首选语言,我这里设置的是简体中文,我就不贴图了,各位请自行选择,英文较好的同学可以忽略此步骤。

2、创建一个 issue

找到工具条上面的 新建/Create 按钮,点击打开弹框表单,项目选择 Community Support - Maven Central (MVNCENTRAL) 就好了,其他就看着填写吧,完了点击 **新建/Create ** 创建一个issue。以下是部分示例,提供给各位同学参考。

image

3、SCM url / Project URL

这两个填写你github/gitee的地址即可。

4、Group Id 说明

这里值得注意的一点是其中的 Group Id, 如果你填写的是个人域名的话,审核时需要验证当前域名是否为你本人所有,如果没有的话可以填写github对应的个人地址。

5、个人域名验证(github个人地址不需要这一步)

个人域名验证也挺简单,需要在你所在的域名管理商控制台中添加一条DNS域名解析记录,类型为 TXT,值为你的Issue地址,类似于 https://issues.sonatype.org/browse/OSSRH-52222 ,添加完成生效后去你的issue下面添加一条评论,告诉他 “这是你自己的域名”,然后等待工作人员的回复,如果没有通过的话他会告诉你具体原因,通过之后如下图,那么就可以正常进行项目发布了。

image

小提示:如何验证自己的TXT记录已经生效了呢?见下图,如果有这样的结果就说明记录生效了

校验教程

6、等待审核

审核通过后平台会告诉你结果,如果没有通过,修改后填写备注信息再次提交等待审核即可,通过后大概如下,意思就是已经为我们准备好了相关信息,可以正常发布项目了。

image

6、最后一步

当你第一个项目发布之后,再回来添加一个评论,告诉平台你已经构建完成,然后可以关闭此issue了。以后再在同一个 Group Id 下发布任何项目都不需要这些流程了。

审核结果

至此,Sonatype的准备工作就结束了。

3、完善 pom.xml

以下是参考列表,加粗部分是比较重要的几个信息:

  • name - 项目名称

  • groupId - 你在issue中申请用到的 Group Id,必须一样,否则发布校验通不过

  • artifactId - 同一个Group下唯一的项目Id

  • version - 项目版本,对应中央库的版本,升级或者发版依赖这个版本号

  • url - 项目地址,可以写你自己的域名也可以写你github/gitee的仓库地址

  • description - 项目描述,发布到中央库会显示这个备注信息

  • licenses - 项目开源协议,根据自己选择添加对应的许可证说明

  • scm - 项目仓库地址,一般就是github/gitee的仓库地址

  • developers - 开发者列表

  • contributors - 贡献者列表,如果有的话

  • distributionManagement - 填写之前sonatype中工作人员审核通过提供给你的地址

  • build - 构建打包

  • inceptionYear - 非必须,成立年份

  • organization - 非必须,组织的话可以加上这个说明

  • profiles - 非必须,环境选择,完善的话可以加上这个

  • dependencies - 非必须,依赖模块

  • issueManagement - 非必须,issue问题管理系统,一般写githu/gitee的issue地址就行了

完整示例

<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.viiyue.plugins</groupId>
    <artifactId>mybatis-mapper</artifactId>
    <version>1.1.1</version>
    <packaging>jar</packaging>
    
    <!-- 描述信息 -->
    <name>mybatis-mapper</name>
    <url>https://github.com/tangxbai/mybatis-mapper</url>
    <description>
        Mybatis generic mapper plugin for solving most basic operations, 
        simplifying sql syntax and improving dynamic execution efficiency
    </description>

    <!-- 项目成立年份,非必须 -->
    <inceptionYear>2017</inceptionYear>
    
    <!-- 许可证,最好是加上避免以后产生不必要的麻烦 -->
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <!-- 仓库地址,scm:xxx:xxx 是一种协议,看着写就行了git的话一般就是scm:git:git -->
    <scm>
        <url>https://github.com/tangxbai/mybatis-mapper.git</url>
        <connection>scm:git:git@github.com:tangxbai/mybatis-mapper.git</connection>
        <developerConnection>scm:git:git@github.com:tangxbai/mybatis-mapper.git</developerConnection>
        <tag>HEAD</tag>
    </scm>

    <!-- 问题管理系统,非必须,写上最好 -->
    <issueManagement>
        <system>GitHub Issue Management</system>
        <url>https://github.com/tangxbai/mybatis-mapper/issues</url>
    </issueManagement>

    <!-- 发布管理,要想发布到中央库就必须要配置的一个节点,以下两个链接可以从issue审核结果中找到 -->
    <!-- 其中id为自定义,后面会在maven/config/settings.xml中配置对应的服务器信息 -->
    <distributionManagement>
        <snapshotRepository>
            <id>ossrh</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
        </snapshotRepository>
        <repository>
            <id>ossrh</id>
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
        </repository>
    </distributionManagement>

    <!-- 开发者列表,个人的话就写自己,团队就罗列所有成员 -->
    <developers>
        <developer>
            <name>tangxbai</name>
            <email>tangxbai@hotmail.com</email>
            <timezone>GMT+8</timezone>
            <url>https://github.com/tangxbai</url>
        </developer>
    </developers>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        
        <!-- License许可证源文件头部信息插件要用的配置,非必须 -->
        <license.licenseName>apache_v2</license.licenseName>
        <license.verbose>false</license.verbose>
        <license.failOnMissing>true</license.failOnMissing>
        <license.failOnUnknown>true</license.failOnUnknown>
        <license.failIfWarning>true</license.failIfWarning>
        <license.failOnForbidden>true</license.failOnForbidden>
        <license.organizationName>${project.name}</license.organizationName>
        <license.sectionDelimiter>#</license.sectionDelimiter>
        <license.processStartTag>Start tag</license.processStartTag>
        <license.processEndTag>End tag</license.processEndTag>
        <license.xxx>...</license.xxx>
    </properties>

    <!-- 模块依赖,非必须 -->
    <dependencies>...</dependencies>

    <!-- 打包插件 -->
    <build>
        <plugins>
            <!-- Maven编译插件,非必须,打包后生成 xxx.jar -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

            <!-- Java源代码插件,非必须,打包后生成 xxx-sources.jar -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Javadoc,文档插件,非必须,打包后生成 xxx-javadoc.jar -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                        <configuration>
                            <!-- Jdk1.8以后文档的生成校验非常严谨,这里可以关掉文档校验-->
                            <doclint>none</doclint>
                            <applyJavadocSecurityFix>false</applyJavadocSecurityFix>
                            <failOnError>false</failOnError>
                            <failOnWarnings>false</failOnWarnings>
                            <additionalparam>-Xdoclint:none</additionalparam>
                            <additionalJOption>-Xdoclint:none</additionalJOption>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- GPG签名校验,必须,这个很重要,上传到中央库时用来验证签名很重要的一个凭证 -->
            <!-- 后面关于GPG签名会详细说到,这里先添加GPG插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- License,非必须,用于在源文件头部生成一段许可证文本注释 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>license-maven-plugin</artifactId>
                <version>2.0.0</version>
                <executions>
                    <execution>
                        <id>generate-license-headers</id>
                        <goals>
                            <goal>update-file-header</goal>
                        </goals>
                        <phase>process-sources</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

至此,项目方面的配置完成。

4、Maven配置

嗯,项目神马的都配置好了,那么又有很多问题来了。。。

1、怎么发布?

Maven自带deploy插件,我们无须在任何配置文件中配置,但如果你想重载该配置,可以在pom.xml中更改默认配置,这里不作过多说明,默认配置就好,其他的不用过多的关心,只要执行以下命令就能帮我们上传代码,不过先别忙着执行命令,接着往下看。

$ mvn clean deply

2、发布到哪儿去?

当然是发布到中央库去了啊,那怎么让maven知道呢?下面是具体配置信息,你也可以结合上面pom.xml整体看看。注意其中的 id 值,前面的篇幅也有提到过,这个值虽然是随便定义的,但是必须和 settings.xml 中的server节点 id 保持一致。

这两个链接是死的,你可以直接复制过去,id的话不想改可以直接使用这个值。

<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
    </repository>
</distributionManagement>

3、以谁的名义发布?

就是你之前注册的 issues.sonatype.org 账号,这个需要让maven知道,所以接下来需要对maven的配置文件进行更改,路径位于:/path/maven/conf/settings.xml,在根节点下添加一个 servers 节点 id 随意,记得和上面保持一致,然后就是你的账号/密码信息。

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    ...
    <servers>
        <server>
            <id>ossrh</id>
            <username>tangxbai</username>
            <password>***</password>
        </server>
    </servers>
    ...
</settings>

至此,Maven的相关配置完成。

5、GPG签名

用途说明

GPG详细的解说请百度/Google查看更详细的文档,Maven中使用主要在项目发布时, 利用非对称密钥对来进行签名校对,以验证上传者是否为你本人,不然谁都可以替你上传甚至更改你的仓库东西了?如果不是你本人那 只能上传而无法正常发布到中央库

小插曲

那有人会说了,网上很多文章步骤都不是这样的啊,关于GPG都放在前几步的,你为什么放在后面来说呢?呃,因为坑太多,踩的吐血,这也是我整个过程中遇到问题最多的一步,所以放在最后来说,当然你也可以先准备好你的GPG信息,以备不时之需,反正早晚也会用到。如果你按照网上的步骤没有任何问题的话,那就注意一点就行了,怎么在其他电脑上使用同样的信息进行GPG签名???你有考虑过吗?,如果没有,那现在想一想。。。

特别强调

GPG签名作为中央库校验应用 很重要 的一个东西,一开始网上各种文章翻了个遍,都没人说这东西的用处,都在盲目的教别人如何如何使用,一大堆无用的命令,混淆视听,甚至不说它在整个流程中的实际用处,是不是非要它不可?有它和没它有什么区别?然后就盲目的踩坑测试,遇到各种各样的问题,你可知道一整天研究这个,然后各种尝试失败又找不到解决方案的痛苦吗???直白的说,脑壳都抠破了,找不到人问,身边没人知道,各种技术群里面一个个都水的无法言语,最后甚至尝试了去掉这个 恶心 的步骤,直接打包上传中央库。。。

然鹅,我真的是太天真了,实际经验告诉我,这TM根本就是必须的啊!!!我嘞个艹,网上文章简直不靠谱到天际,晕死!也没人细说其中可能会遇到的问题。。。唉,第一次真的很痛。。。

记住:GPG在我们将项目发布到中央库的过程中,是一个很重要的东西,不能省略,所以不要像我一样去尝试省略这个步骤了,只会浪费时间,不管遇到什么问题,都要冷静冷静再冷静,总是需要攻克这个难关的。

安装Gpg4win

https://gpg4win.org/thanks-for-download.html 这是下载地址,有兴趣的同学可以下载下来研究研究,这里关于此工具我不会作过多的说明,网上其他所有文章都是在这个的基础上进行的,你也都跳不过这个工具,但实际证明这东西没什么卵用,而且网速慢的话还得等待它下载然后安装,个人觉得浪费时间,你如果想用这个东西,请自行百度/Google。。。

Git/GPG

实际上我们的git程序 自带gpg命令,这也就是我上面说为什么可以略过Gpg4win的一个原因,如果各位有疑虑的话,请打开你的 Git bash UI,然后输入 gpg --version 命令试试看会不会报 gpg: command not found ,如果没有报错的话,那是应该的。。。如果失败的话,请检查你的git版本是否太低,或者是不是太久没有升级了,我也没去研究过git到底是多少版本开始加入此命令的,貌似从git 2.x以后都有这个命令,不过这里也有一个坑,后面会说到。。。

在下使用的是win7系统,git某目录结果如下,需要确认的同学请自行查看相关目录,Mac系统的略过,我也不知道,请自行探索。。。

GIT-GPG

提醒事项

如果你安装了Gpg4win工具的话,程序会自动在你的电脑添加一个环境变量,你可以在任何命令窗口直接执行gpg命令,如果你和我一样嫌麻烦没有安装,则必须在 Git bash UI 命令行依赖git而执行,注意了,各位同学。。。

再有,在安装了Gpg4win的前提下,就不要在 git bash ui 命令行中执行了,因为在git的命令行中执行使用的是git自带的gpg程序,而不是你安装的程序。

基本命令

基本命令 备注说明
gpg --gen-key 生成密钥
gpg --gen-revoke [ID] 生成密钥撤销证书
gpg --armor --output [文件路径] --export [ID] 导出指定公钥到指定文件
gpg --armor --output [文件路径] --export-secret-keys [ID] 导出指定私钥钥到指定文件
gpg --keyserver [服务器] --send-keys [ID] 上传到密钥服务器
gpg --keyserver [服务器] --recv-keys [ID] 检测是否上传成功(需要等待一两分钟才行)
gpg --import [密钥文件] 导入你已有的密钥到当前电脑中
gpg --keyserver [服务器] --search-keys [ID] 从服务器拉取指定ID的密钥到当前电脑
... 其它更多命令自行百度/Google

生成密钥

$ gpg --gen-key

gpg (GnuPG) 2.2.17; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1 # 默认选择第1个就好了
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048 # 长度越长密钥越安全,这里使用默认长度2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0 # 密钥过期时间,0永不过期,不常变更的话建议选择0,永不过期
Key does not expire at all
Is this correct? (y/N) y # 输入y
Key is valid for? (0) 0 # 输入0
Key does not expire at all
Is this correct? (y/N) y # 输入y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: tangxbai
Email address: tangxbai@hotmail.com
Comment: com.viiyue.secrets # 备注信息选填
You selected this USER-ID:
    "tangxbai (com.viiyue.secrets) <tangxbai@hotmail.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o # 需要更改请仔细阅读,没问题输入 o
You need a Passphrase to protect your secret key.

passphrase: ***** # 输入你的密钥密码,不要乱填,这个很重要,后面也要用到

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
....+++++
+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
....+++++
..+++++
gpg: /c/Users/Administrator/.gnupg/trustdb.gpg: trustdb created
gpg: key [ID] marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/[ID] 2019-10-14 # ID很重要啊,保管好它,很多地方需要用到它
      Key fingerprint = *********
uid                  tangxbai (com.viiyue.secrets) <tangxbai@hotmail.com>
sub   2048R/[ID] 2019-10-14 # 这个ID没有仔细研究过,有兴趣的同学可以研究研究

至此,出现以上信息就代表密钥已经生成好了,这个步骤我尝试了N多次,基本不会出现什么问题,有问题的同学可以私信在下。

提醒事项

这里需要重点说明一个东西,这可是我经历若干步骤之后通过对比才发现的,也有可能你早就知道了,但是恕在下愚笨,网上就是没有找到过关于此的任何文档说明,其中的一个名叫 secring.gpg 的文件尤为重要,于是经过多番资料查证,它是你的私人 密钥,用于提供文件签名的很重要的一个文件,而它只有在第一次生成密钥时才会产生,所以保管好它。

image

关于 secring.gpg 的说明

为什么我会说这个 私钥 文件尤为重要呢?因为有了它你才能在 其他电脑 上发布你的项目,相信你也不想只在某一台机器上操作吧,灵活一点,什么年代了,我们当然需要 Coding everywhere 啊,如果缺少这个文件的话,执行 mvn clean install 或者 mvn clean deploy 会出现以下错误:

$ mvn clean install/deploy
...
# 隐约记得貌似是这样的一个错,懒得重试去截图了,将就看吧。。。
gpg: no default secret key: No secret key
gpg: sign failed: No secret key
...

所以再次提醒一下各位,保管好它。

导出密钥

# 导出公钥
$ gpg --armor --output public-key.txt --export [ID]
# 导出私钥
$ gpg --armor --output private-key.txt --export-secret-keys [ID]

--armor 这个命令不加也可以,加上是以ASCII明码的形式保存,否则是加密过的一串看不懂的东西。

上传到服务器

# 上传到服务器,ID是你上面生成密钥的ID
$ gpg --keyserver [key-server] --send-keys [ID]
# 检测是否上传成功(需要等待几分钟才会生效)
$ gpg --keyserver [key-server] --recv-keys [ID]

需要注意的是,maven中央库为了验证文件签名,提供了多个签名服务器供我们使用,它会尝试从每台服务器拉取你的公钥然后说文件做对比,但是我们上传了密钥信息之后,需要等待很长一段时间,它才会将你的信息同步到其他密钥服务器上,这个过程很漫长,反正我等待了好几个小时都没搞定了,可能同步程序只会在特定时间激活吧,所以我们就不要瞎等了,可以手动将信息推送到各个服务器上,这样就缩短了等待时间,值得注意的是,很多服务器貌似是国外网站,能访问,但速度很慢,还是需要等待几分钟。

公钥服务器列表

这里我整理了一份可能会涉及的服务器列表,各位同学可以手动上传到这些服务器上,命令就用上面的上传命令就行。

算了,我还是贴一份吧。。。分开执行,不要全部一起执行,待成功之后再执行下一个,成功信息不就不贴了,有点认知的话都大概知道输出什么信息代表成功吧?

$ gpg --keyserver hkp://pool.sks-keyservers.net --send-keys [ID]
$ gpg --keyserver hkp://keyserver.ubuntu.com --send-keys [ID]
$ gpg --keyserver hkp://subkeys.pgp.net --send-keys [ID]
$ gpg --keyserver hkp://pgp.mit.edu --send-keys [ID]
$ gpg --keyserver hkp://www.gpg-keyserver.de --send-keys [ID]

提醒事项

上传密钥文件到服务器这个步骤也是必须的,包括保证它必须能被检测到!因为上传到maven中央库暂存区之后,正式发布时平台会从密钥服务器拉取对应 ID 的公钥文件来校验你的项目文件签名是否正确,否则中央库会报 No public secret key 的一个错误,所以尽量保证你的密钥能够上传成功,如果网络出错的话,建议多尝试几次。

哦,对了,这里还得废话的说一下pom.xml文件中如果缺少GPG插件会出现的问题,当我们上传成功后,兴高采烈的在中央库暂存区中点击项目Close时,平台会无情的报 Missing signature 的一个错,也就是你的项目缺少签名信息,网上搜罗了很久未果,最后回想了一下,可能这个插件是必须的。。。最后通过验证,确实如此。

其他电脑使用GPG

这个问题也是搜罗了很久很久,不过最后还是解决了,值得鼓励。两种方式,一种是将你上面导出来的密钥文件通过命令的方式导入到电脑,另一种是从服务器拉取。

# 直接导入密钥文件
$ gpg --import [密钥文件]
# 从服务器拉取,服务器请参考上面罗列的服务器列表
$ gpg --keyserver [key-server] --search-keys [ID]

gpg-agent

这个命令这里不会用到,主要是执行maven项目打包或者上传时gpg签名可能会出现的问题,具体错误记不太清楚了,反正大致意思就是需要运行一下这个命令,低版本的git中可能没有这个工具,需要升级到最新版的git程序,简单运行一下就行了。

# 检测是否有此命令
$ gpg-agent --version
# 运行此命令
$ gpg-agent

至此,GPG的使用和注意事项也就差不多了。

6、上传项目

这个步骤没有什么值得过多说明,唯一需要保证的就是你的项目普通打包安装没有任何问题。。。

执行命令

$ mvn clean deploy

...
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/com/viiyue/plugins/mybatis-mapper/1.1.0/mybatis-mapper-1.1.0-sources.jar.asc (499 B at 1.2 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/snapshots/com/viiyue/plugins/mybatis-mapper/maven-metadata.xml
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/com/viiyue/plugins/mybatis-mapper/maven-metadata.xml (2 KB at 1.5 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/com/viiyue/plugins/mybatis-mapper/1.1.0/mybatis-mapper-1.1.0-javadoc.jar.asc
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/com/viiyue/plugins/mybatis-mapper/1.1.0/mybatis-mapper-1.1.0-javadoc.jar.asc (499 B at 1.2 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/com/viiyue/plugins/mybatis-mapper/maven-metadata.xml
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/com/viiyue/plugins/mybatis-mapper/maven-metadata.xml (2 KB at 1.1 KB/sec)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 52.229 s
[INFO] Finished at: 2018-07-14T22:14:28+08:00
[INFO] Final Memory: 25M/297M
[INFO] ------------------------------------------------------------------------

结果分析

当你执行命令得到以上结果,那么恭喜你,你已经成功80%了,即将站上人生顶峰,走向迎接白富美/高富帅的道路,开玩笑,扯远了。。。

7、回到maven管理平台

如果你还不知道管理平台的地址,那么在下不辞辛劳的为您再贴一遍吧。。。

登录管理平台,账号/密码就是你当初注册的那个账号。

发布项目

进入主页面之后,进入 Staging Repositories 暂存区,如果你的项目没有设置发布插件的话,则会进入到这里,找到你要操作的项目,选中它,你会发现上方的 Close 按钮亮起,当你确认上传无误之后,你可以点击 Close 按钮,关闭掉这个仓库,不允许再次上传。如果关闭成功,点击 Refresh 以后会你会发现 Release 按钮亮起,点击它即可发布。如果关闭失败,你可以看看下方的界面,查找一下失败原因,再次上传代码,关闭后发布。

如果你有仔细阅读我上面的 废话 的话,这里应该能顺利并且发行你的项目。

image

可能会出现以下问题

# 现象一,缺少GPG文件签名,老老实实配置好你的GPG吧,唉。。。
Missing signature 
# 现象二,未在任何公钥服务器找到你的公钥
No public key: Key with id: (XXXXX) was not able to be located (oss.sonatype.org) 

关于第二点,你可以参考以下下网站:

https://stackoverflow.com/questions/19462617/no-public-key-key-with-id-xxxxx-was-not-able-to-be-located-oss-sonatype-org

关于这种情况我上面也已经说了,要么你没有将你的公钥上传到服务器,要么服务器还未完全同步你的公钥信息,为了缩短这个同步过程,你可以分别将公钥信息手动上传到多个服务器,关于此,请回退到上面 GPG签名 再看看。

至此,整个过程中所有我遇到过的问题都以 废话 的形式罗列了出来,希望各位同学不要再遇到这些问题了,如果遇到这些问题也不要紧张,希望此文能帮到你。

何时能生效?

当你点击完 Release 之后,记得回去你的问题管理系统( https://issues.sonatype.org )回复一下你已经发行了你的第一个项目,从审核通过后开始算的话,大概间隔几分钟到一个小时之后在Central( https://search.maven.org/ )中就可以搜到了,但这只是一部分网站能搜到,像我们平时使用的阿里云Maven私服(http://maven.aliyun.com)和常用的Maven库( https://mvnrepository.com/ )则需要等待一到两天才会生效。实测应该不会超过一天。

8、最后

至此,如果你到了这里,那就恭喜各位同学,你拥有了自己的第一个公开的可随处使用的项目,凡事开头难,第一次难免各种痛苦,以后就好了,在同一个 Group Id 下发布的任何项目都不需要这么麻烦了,直接执行 deploy 即可,然后等一到两天各大中央库就会同步生效了。

虽然篇幅废话和文字比较多,但如果有帮助到你,那我很高兴,如果您觉得对您有任何帮助,可以点个赞或者分享给有需要的小伙伴。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容