一篇搞定发布自己的类库到Maven中央仓库

发布时间 2023-12-12 16:36:59作者: 一块白板

在Maven项目中,90%以上的jar包是通过pom文件直接从开源仓库中获取依赖jar包文件,然后在项目中进行集成使用。
此时如果你有一个开源项目,那么如何将该开源项目发布到Maven中央仓库,让其他人可以方便的使用,而不是先下载jar,然后install的本地?
本文将通过一步步的操作带领大家讲自己的开源项目发布到Maven中央仓库(Maven Central Repository)中,https://mvnrepository.com/。
Maven中央仓库并不支持直接发布jar包,需要将jar包发布到一些指定的第三方Maven仓库,然后该仓库再将jar包同步到Maven中央仓库,Sonatype便是这样的角色

准备工作

  1. 注册Github账户,在申请的时候需要用到GroupId,这边如果没有自己的网站及域名建议注册Github。

  2. 注册Sonatype账户,注册地址:sonatype sign up

    1. Username和Password作为登录的账号密码
    2. 密码有强度要求
    3. Email用于后续关联的通知,务必使用真实地址

项目发布申请

  1. 点击导航栏的"新建"进行项目发布申请创建。
    image

    通过在JIRA上创建issue来申请发布新的jar包,Sonatype的工作人员会进行审核,一般按照要求填写不会有问题。

    注意:

    1. Group Id:如果有域名可以填写自己的域名,如果没有可以使用GithubGiteeGitlib等地址例如:io.github.you_account,此处注意必须是 io
    2. Project UrlSCM Url建议都采用Git地址,其中SCM的地址需要带.git
    3. Already Synced to Central选择No
  2. 提交后等待一小段时间再来查看刚提交的问题。你会收到类似下图的回复。此时会要求进行Group Id的所有权验证。

    image

    如果填写的是Github则会要求创建一个指定的仓库,创建一个即可。

    如果填写的是自己的自己的域名则会要求创建个指定文件到此域名下。

  3. 填写按要求完成后修改状态为开放状态 。点击Wait for Reponse在弹出的状态列表中选择 开放
    image

    如果按要求完成了所有的操作等待一段时间后一般就自动通过了。这时会给予推送服务器的地址,后续所有的相关地址都需要用到。
    image

    到此发布申请也就完成了。

安装GPG

发布到Maven仓库中的所有文件都要使用GPG签名,以保障完整性。因此,我们需要在本地安装并配置GPG。

  1. 进入gnupg下载,https://www.gnupg.org/download/index.html

  2. 根据操作系统下载不同的版本并进行安装。

    此处以Windows为例:

    建议下载2个安装包分别为

    1. Gpg4win:Full featured Windows version of GnuPG

      此工具通过Windows窗口进行密钥的管理。

    2. download sig:Simple installer for GnuPG 1.4

      此工具用于后续Maven发布使用

  3. 创建密钥

    1. Gpg4win

      生成秘钥,按步步骤提示进行操作
      必须勾选密码
      image
      按提示输入密码
      image

      秘钥生成好后,右键选择密钥,需要你把公钥上传到公共服务器供sonatype验证。
      image

    2. 命令行

      生成秘钥,按步骤提示进行操作

      gpg --generate-key
      
      # 生成结果
      gpg (GnuPG/MacGPG2) 2.2.32; Copyright (C) 2021 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.
      注意:使用 “gpg --full-generate-key” 以获得一个全功能的密钥生成对话框。
      GnuPG 需要构建用户标识以辨认您的密钥。
      真实姓名: xxxxxxx
      电子邮件地址: xxxxxxx@foxmail.com
      您选定了此用户标识:
          “xxxxxxxx <xxxxx@foxmail.com>”
      更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? u
      更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? o
      我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
      、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
      发生器有更好的机会获得足够的熵。
      我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘
      、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数
      发生器有更好的机会获得足够的熵。
      gpg: 密钥 54EC3C8FA3A5B50F 被标记为绝对信任
      gpg: 目录‘/Users/xxxxxxxxx/.gnupg/openpgp-revocs.d’已创建
      gpg: 吊销证书已被存储为‘/Users/xxxxxxxxx/.gnupg/openpgp-revocs.d/xxxxxxxxxxxxxxxxxxxxxxxxxxxx.rev’
      公钥和私钥已经生成并被签名。
      pub   rsa3072 2021-12-06 [SC] [有效至:2023-12-06]
            8BDxxxxxxxxxxxxxxxxxxxxxxxxxxxxB50F
      uid                      xxxxxxxx <xxxxxxxx@foxmail.com>
      sub   rsa3072 2021-12-06 [E] [有效至:2023-12-06]
      

      秘钥生成好后,需要你把公钥上传到公共服务器供sonatype验证。

      官网教程里有三个地址可以用:

      • keyserver.ubuntu.com
      • keys.openpgp.org
      • pgp.mit.edu
      ➜  ~ gpg --keyserver pgp.mit.edu:11371 --send-keys 8BD96B0EA18E5162B94EA7F754EC3C8FA3A5B50F
      gpg: 正在发送密钥 54EC3C8FA3A5B50F 到 pgp.mit.edu:11371
      gpg: 发送至公钥服务器失败:文件结尾
      gpg: 发送至公钥服务器失败:文件结尾
      ➜  ~ gpg --keyserver keyserver.ubuntu.com --send-keys 8BD96B0EA18E5162B94EA7F754EC3C8FA3A5B50F
      gpg: 正在发送密钥 54EC3C8FA3A5B50F 到 hkp://keyserver.ubuntu.com
      gpg: 发送至公钥服务器失败:Network is unreachable
      gpg: 发送至公钥服务器失败:Network is unreachable
      ➜  ~ gpg --keyserver pgp.mit.edu:11371 --send-keys 54EC3C8FA3A5B50F
      gpg: 正在发送密钥 54EC3C8FA3A5B50F 到 pgp.mit.edu:11371
      gpg: 发送至公钥服务器失败:文件结尾
      gpg: 发送至公钥服务器失败:文件结尾
      

配置setting.xml

setting.xml为Maven的全局配置文件,一般路径为$MAVEN_HOME/conf/settings.xml

找到Services节点进行如下配置

<servers>
    <server>
        <id>ossrh</id>
        <username>你的Sonatype账号</username>
        <password>你的Sonatype密码</password>
    </server>
</servers>

找到profiles节点进行如下配置,gpg.executable节点建议配置第二个安装包安装的gpg路径,这一步一定要做不然容易发布的时候提示找不到gpg。

<profiles>
      <profile>
          <id>ossrh</id>
          <activation>
              <activeByDefault>true</activeByDefault>
          </activation>
          <properties>
              <gpg.executable>"D:\Program Files (x86)\GnuPG\bin\gpg.exe"</gpg.executable>
              <gpg.passphrase>你的密钥创建时候的密码</gpg.passphrase>
          </properties>
      </profile>
</profiles>

配置pom.xml

以下为一些关键点的配置示例

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <!--Maven相关信息配置-->
    <name>fluent-validation</name>
    <url>https://github.com/yikuaibaiban/fluent-validation</url>
    <description>fluent-validation is a streaming validation framework.</description>
    <!--Issue 配置-->
    <issueManagement>
        <system>Github Issue</system>
        <url>https://github.com/yikuaibaiban/fluent-validation/issues</url>
    </issueManagement>
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>https://apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>
    <!--开发人员信息配置-->
    <developers>
        <developer>
            <name>yikuaibaiban</name>
            <email>xxxx@xxxx.com</email>
            <timezone>+8</timezone>
        </developer>
    </developers>
    <!--scm信息配置-->
    <scm>
        <url>https://github.com/yikuaibaiban/fluent-validation</url>
        <connection>scm:https://github.com/yikuaibaiban/fluent-validation.git</connection>
        <developerConnection>scm:git:https://github.com/yikuaibaiban/fluent-validation.git</developerConnection>
    </scm>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <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>
                                <id>attach-sources</id>
                                <goals>
                                    <goal>jar-no-fork</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- Javadoc -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <version>3.5.0</version>
                        <configuration>
                            <windowtitle>${project.name}</windowtitle>
                            <doctitle>${project.name}</doctitle>
                            <show>private</show>
                            <detectLinks>false</detectLinks>
                            <detectOfflineLinks>true</detectOfflineLinks>
                            <linksource>true</linksource>
                            <detectJavaApiLink>true</detectJavaApiLink>
                            <source>8</source>
                        </configuration>
                        <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.6</version>
                        <executions>
                            <execution>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <distributionManagement>
                <snapshotRepository>
                    <id>ossrh</id>
                    <url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
                </snapshotRepository>
                <repository>
                    <id>ossrh</id>
                    <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
                </repository>
            </distributionManagement>
        </profile>
    </profiles>
</project>

发布到Maven中央仓库

推送代码

  1. 使用命令行发布 mvn clean deploy -P release
  2. 使用Idea发布
    image

后续操作(必须要操作)

此时进入https://s01.oss.sonatype.org并登录(登录的账号密码与刚开始注册的账号密码一致)查看发布好的构件,点击左侧的Staging Repositories。

此时需注意,如果项目中版本信息为1.0.0-SNAPSHOT,即SNAPSHOT为后缀,则发布的项目位于Snapshots目录下。在左上角的Artifact Search中能够搜到。

如果是Release后缀,则可直接在Staging Repositories中看到(有可能要稍等一下,等待平台处理)。
选中对于的repository之后,点击的close,close时会检查发布的构件是否符合要求。若符合要求,则close成功,成功之后点击箭头所指的release,即可正式将jar包发布到Sonatype OSSRH仓库。
image

当点击Release之后,邮件中会收到Issues变化的信息,提示同步已经被激活,正常10分钟就可以更新同步。

release成功大概2个小时之后,该构件就会同步到Maven中央仓库,届时会有邮件通知。

实践过程中发现十分钟之内已经成功同步到https://repo1.maven.org/的中央仓库当中。

逐步的其他Maven仓库,包括阿里镜像都会进行同步。