Maven Central 上传(发布)JAR 包流程

将一个 Java 工程的 JAR 包发布到 Maven Central,可以让其他开发者只用 mvn dependency 就能引用你的库。这是许多开源组件的标准流程,但会涉及签名、账号、工件验证等步骤。

本文将以简洁且可复用的方式,带你从 0 到发布成功

官方文档教程


📌 一、准备工作

1. 注册账号

https://central.sonatype.com右上角的"登录"。

支持通过 Google 或 GitHub 进行社交账号登录。也可以自定义用户名和密码。如果您选择使用社交账号登录,Sonatype 将获得与您的社交账号关联的电子邮件地址的访问权限。


2. 申请 Maven Central Namespace(GroupId)

在发布前必须申请你的 groupId,比如:

复制代码
io.github.myusername
io.gitlab.myusername
io.gitee.myusername
io.bitbucket.myusername
com.company.project
# 域名
cn.ha

⚠️ 注意:Maven Central 不允许你使用未授权的 Namespace,如果你没有对应域名的所有权,会被拒绝。

最推荐的方式是使用 GitHub

复制代码
io.github.<github 用户名>

Sonatype 不会拒绝 GitHub namespace,非常简单。

https://central.sonatype.com/publishing/namespaces 点击 Register New Namespace。


📌 二、在本地生成 GPG 密钥

1. 安装 GnuPG

从 https://www.gnupg.org/download/下载 GnuPG 二进制文件。

mac 可以通过 Homebrew 安装 GnuPG

复制代码
-- 安装
brew install gnupg
-- 显示 GnuPG 的版本信息
gpg --version

2.生成密钥对

Maven Central 要求所有 artifacts 必须签名。

复制代码
gpg --full-generate-key

推荐配置:

  • Type: RSA & RSA

  • Key size: 4096

  • Expire: 0(永不过期)

查看 key:

复制代码
gpg --list-keys

然后上传公钥到 keyserver(必须):

复制代码
gpg --keyserver keyserver.ubuntu.com --send-keys <你的KEY_ID>

📌 三、在项目中配置 Maven 发布所需内容

1. pom 文件

Maven Central 有要求:

✔ 必须包含 source JAR

✔ 必须包含 javadoc JAR(可用 empty-javadoc)

✔ 必须 GPG 签名

✔ 必须有完整的 POM 信息(license、开发者、scm 地址等)

以下为的 pom.xml 示例(可直接复制):

XML 复制代码
<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.github.tom-hu</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>my-library</name>
    <description>A simple Java utility library</description>
    <url>https://github.com/tom-hu/my-library</url>

    <!-- License -->
    <licenses>
        <license>
            <name>Apache License 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <!-- 开发者信息 -->
    <developers>
        <developer>
            <id>tomhu</id>
            <name>Tom Hu</name>
            <url>https://github.com/tom-hu</url>
        </developer>
    </developers>

    <!-- SCM 仓库信息 -->
    <scm>
        <connection>scm:git:git://github.com/tom-hu/my-library.git</connection>
        <developerConnection>scm:git:ssh://github.com:tom-hu/my-library.git</developerConnection>
        <url>https://github.com/tom-hu/my-library</url>
    </scm>

    <build>
        <plugins>

            <!-- JAR 源码和 javadoc -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.6.2</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>3.1.0</version>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                        <configuration>
                            <passphraseServerId>gpg.passphrase</passphraseServerId>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- 核心:自动上传到 Central -->
            <plugin>
                <groupId>org.sonatype.central</groupId>
                <artifactId>central-publishing-maven-plugin</artifactId>
                <version>0.9.0</version>
                <extensions>true</extensions>
                <configuration>
                    <publishingServerId>central</publishingServerId>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>

2. settings.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/settings-1.0.0.xsd">

    <!-- 用于 Maven Central 发布的账号配置 -->
    <servers>
        <server>
            <!-- 必须与 pom.xml 中 distributionManagement 的 id 一致 -->
            <id>central</id>
            <username>token</username>
            <password>tokenx</password>
        </server>

        <server>
            <id>gpg.passphrase</id>
            <passphrase>你的GPG密码</passphrase>
        </server>
    </servers>

    <!-- 可选配置:提高构建速度(不限于发布) -->
    <mirrors>
        <mirror>
            <id>aliyunmaven</id>
            <mirrorOf>*</mirrorOf>
            <url>https://maven.aliyun.com/repository/public</url>
        </mirror>
    </mirrors>

    <!-- 可选项:默认使用 release profile,用于签名和发布 -->
    <profiles>
        <profile>
            <id>release</id>
            <!-- 如需额外配置可写在这里 -->
        </profile>
    </profiles>

    <activeProfiles>
        <activeProfile>release</activeProfile>
    </activeProfiles>
</settings>

📌 四、执行发布命令

1. 发布:

XML 复制代码
mvn clean deploy -P release

等待 Deployments published。

https://central.sonatype.com/ 搜索查看。

相关推荐
程序员小假13 小时前
我们来说一下 MySQL 的慢查询日志
java·后端
独自破碎E13 小时前
Java是怎么实现跨平台的?
java·开发语言
To Be Clean Coder13 小时前
【Spring源码】从源码倒看Spring用法(二)
java·后端·spring
xdpcxq102913 小时前
风控场景下超高并发频次计算服务
java·服务器·网络
想用offer打牌14 小时前
你真的懂Thread.currentThread().interrupt()吗?
java·后端·架构
橘色的狸花猫14 小时前
简历与岗位要求相似度分析系统
java·nlp
独自破碎E14 小时前
Leetcode1438绝对值不超过限制的最长连续子数组
java·开发语言·算法
用户917439653914 小时前
Elasticsearch Percolate Query使用优化案例-从2000到500ms
java·大数据·elasticsearch
yaoxin52112314 小时前
279. Java Stream API - Stream 拼接的两种方式:concat() vs flatMap()
java·开发语言
坚持学习前端日记15 小时前
2025年的个人和学习年度总结以及未来期望
java·学习·程序人生·职场和发展·创业创新