附录 1:[特殊字符] Maven Central 发布完整指南:从零到成功部署

本文详细记录了将 Java 项目发布到 Maven Central 的完整流程,包括遇到的坑和解决方案。适合小白和高级开发者参考。

案例代码:https://github.com/nemoob/simpleflow

📋 目录

🎯 项目背景

项目:Simple Flow Framework

  • 一个轻量级、灵活的 Java 工作流引擎
  • 多模块 Maven 项目
  • 目标:发布到 Maven Central 供全球开发者使用

🔄 发布流程概览

准备阶段 Sonatype 账户设置 GPG 密钥配置 项目配置 本地测试 本地部署配置 本地部署到 Maven Central 创建 Sonatype 账户 申请 GroupId 配置 GPG 密钥 更新 pom.xml 配置 settings.xml 设置环境变量 本地构建测试 GPG 签名测试 部署测试 设置环境变量 本地部署 验证发布

📝 详细步骤

1. Sonatype 账户设置

1.1 注册账户
  1. 访问 Sonatype Central

  2. 使用 GitHub 登录

    • 选择 "Sign in with GitHub"
    • 授权 Sonatype 访问你的 GitHub 账户
    • 完成 GitHub OAuth 认证
  3. 创建 Sonatype 账户

    • 填写个人信息(邮箱、姓名等)
    • 同意服务条款
    • 完成账户创建
1.2 申请 GroupId
  1. 创建 Namespace

    • 登录后点击 "Create Namespace"
    • 输入你想要的 GroupId(如:io.github.nemoob
    • 选择命名空间类型(通常选择 "GitHub")
  2. 验证 GitHub 仓库所有权

    • 系统会要求你验证 GitHub 仓库的所有权
    • 创建或选择一个 GitHub 仓库
    • 在仓库中创建一个文件来验证所有权
  3. 等待审核

    • 提交申请后等待审核
    • 通常需要 1-2 个工作日
    • 审核通过后会收到邮件通知
1.3 验证步骤
  1. 检查申请状态

  2. 验证 GitHub 仓库

    • 确保你的 GitHub 仓库是公开的
    • 确保仓库名称与申请的 GroupId 匹配
    • 例如:GroupId io.github.nemoob 对应仓库 nemoob/simpleflow
  3. 测试认证

    • 在 Sonatype Central 中查看你的账户信息
    • 确认你有发布权限
    • 检查 API Token 是否可用
1.4 获取认证信息
  1. 获取用户名和密码

    • 用户名:通常是你的 GitHub 用户名
    • 密码:使用 Sonatype 账户密码或 API Token
  2. 生成 API Token(推荐)

    • 在 Sonatype Central 中生成 API Token

    • 保存 Token 用于后续认证

    • 设置环境变量:

      bash 复制代码
      export OSSRH_USERNAME=your_github_username
      export OSSRH_PASSWORD=your_api_token
  3. 验证认证信息

    • 测试登录 Sonatype Central
    • 确认可以访问你的 Namespace
    • 检查发布权限

2. GPG 密钥配置

2.1 生成 GPG 密钥
bash 复制代码
# 生成 GPG 密钥对
gpg --gen-key

# 查看公钥
gpg --armor --export your-email@example.com

# 查看私钥
gpg --armor --export-secret-key your-email@example.com
2.2 上传公钥到公钥服务器
bash 复制代码
# 上传公钥
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID

3. 项目配置

3.1 更新 pom.xml
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>

    <groupId>io.github.nemoob</groupId>
    <artifactId>simple-flow-parent</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <name>Simple Flow Framework</name>
    <description>A lightweight, flexible workflow engine for Java applications</description>
    <url>https://github.com/nemoob/simpleflow</url>

    <!-- 开发者信息 -->
    <developers>
        <developer>
            <id>nemoob</id>
            <name>nemoob</name>
            <email>yang_zhong_ren@aliyun.com</email>
        </developer>
    </developers>

    <!-- SCM 信息 -->
    <scm>
        <connection>scm:git:https://github.com/nemoob/simpleflow.git</connection>
        <developerConnection>scm:git:ssh://github.com/nemoob/simpleflow.git</developerConnection>
        <url>https://github.com/nemoob/simpleflow</url>
    </scm>

    <!-- 许可证 -->
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <!-- 发布配置 -->
    <distributionManagement>
        <snapshotRepository>
            <id>ossrh</id>
            <name>OSS Sonatype Snapshots</name>
            <url>https://central.sonatype.com/content/repositories/snapshots</url>
        </snapshotRepository>
        <repository>
            <id>ossrh</id>
            <name>OSS Sonatype Releases</name>
            <url>https://central.sonatype.com/content/repositories/releases</url>
        </repository>
    </distributionManagement>

    <build>
        <!-- 使用 Sonatype Central 官方推荐的插件 -->
        <plugins>
            <!-- Sonatype Central 发布插件 -->
            <plugin>
                <groupId>org.sonatype.central</groupId>
                <artifactId>central-publishing-maven-plugin</artifactId>
                <version>0.4.0</version>
                <extensions>true</extensions>
                <configuration>
                    <publishingServerId>ossrh</publishingServerId>
                    <tokenAuth>true</tokenAuth>
                </configuration>
            </plugin>

            <!-- 源码插件 - 官方要求 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Javadoc 插件 - 官方要求 -->
            <plugin>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <additionalOptions>
                        <!-- 跳过严格的 JavaDoc 检查 -->
                        <additionalOption>-Xdoclint:none</additionalOption>
                    </additionalOptions>
                </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>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
3.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 
          http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <servers>
    <!-- Sonatype Central 服务器配置 -->
    <server>
      <id>ossrh</id>
      <username>${env.OSSRH_USERNAME}</username>
      <password>${env.OSSRH_PASSWORD}</password>
    </server>
  </servers>

  <profiles>
    <profile>
      <id>ossrh</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <gpg.executable>gpg</gpg.executable>
        <gpg.passphrase>${env.GPG_PASSPHRASE}</gpg.passphrase>
      </properties>
    </profile>
  </profiles>

</settings>

4. 本地部署配置

4.1 设置环境变量

在本地环境中设置以下环境变量:

bash 复制代码
# 设置 Sonatype 认证信息
export OSSRH_USERNAME=your_github_username
export OSSRH_PASSWORD=your_api_token_or_password

# 设置 GPG 密码
export GPG_PASSPHRASE=your_gpg_passphrase
export GPG_TTY=$(tty)

注意:

  • OSSRH_USERNAME: 通常是你的 GitHub 用户名
  • OSSRH_PASSWORD: 可以是 Sonatype 账户密码或 API Token(推荐使用 API Token)
  • GPG_PASSPHRASE: 你的 GPG 密钥密码
4.2 本地部署命令
bash 复制代码
# 构建并部署到 Maven Central
mvn clean install deploy -DskipTests -s settings.xml.template
4.3 验证结果

https://central.sonatype.com/publishing/deployments

看到需要验证,点击 Publish,大概等待 5-10 分钟即可。

最后在 https://central.sonatype.com/search?q=io.github.nemoob 搜索就可以看到结果了。

🐛 遇到的坑和解决方案

坑 1: 401 认证错误 ❌

错误信息:

复制代码
Failed to deploy artifacts: Could not transfer artifact ... 401 Content access is protected by token

原因:

  • 使用了错误的 Sonatype URL
  • 认证信息不正确

解决方案:

  • 更新 URL 为新的 Sonatype Central 地址:https://central.sonatype.com/
  • 确保 GitHub Secrets 中的认证信息正确

坑 2: GPG 签名失败 ❌

错误信息:

复制代码
Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:3.1.0:sign (sign-artifacts) on project simple-flow-parent: Exit code: 2

原因:

  • GPG 无法正确访问终端
  • 环境变量配置不正确

解决方案:

bash 复制代码
# 设置 GPG 环境变量
export GPG_TTY=$(tty)
export GPG_AGENT_INFO=""

# 测试 GPG 签名
echo "test message" | gpg --clearsign

坑 3: 找不到 Artifact ❌

错误信息:

复制代码
Could not find artifact io.github.nemoob:simple-flow-api:jar:1.0.0-20250822.143840-1

原因:

  • 构建顺序不正确
  • 依赖的模块没有先构建

解决方案:

bash 复制代码
# 按正确顺序构建所有模块
mvn clean install -DskipTests -s settings.xml.template

# 然后部署
mvn deploy -DskipTests -s settings.xml.template

坑 4: GroupId 不匹配 ❌

错误信息:

复制代码
Could not find artifact io.github.nemoob:simple-flow-parent:pom:1.0.0-20250822.064503-1

原因:

  • 父 POM 和子模块的 GroupId 不一致
  • 依赖关系配置错误

解决方案:

  • 确保所有模块的 GroupId 都使用 io.github.nemoob
  • 检查所有子模块的 pom.xml 中的依赖配置

坑 5: Javadoc 生成失败 ❌

错误信息:

复制代码
Could not find artifact io.github.nemoob:simple-flow-expression:jar:javadoc:1.0.0-20250822.135945-1

原因:

  • Javadoc 插件配置不正确
  • 某些模块缺少 Javadoc

解决方案:

bash 复制代码
# 跳过 Javadoc 生成
mvn clean deploy -DskipTests -Dmaven.javadoc.skip=true -s settings.xml.template

# 或者修复 Javadoc 配置
mvn javadoc:jar -pl simple-flow-expression

坑 6: Maven Source 插件重复执行 ❌

错误信息:

复制代码
Presumably you have configured maven-source-plugn to execute twice times in your build. You have to configure a classifier for at least on of them.

原因:

  • Maven Source 插件被配置了两次
  • 父 POM 和子模块都有配置

解决方案:

  • 移除重复的插件配置
  • 只在父 POM 中配置一次
  • 或者为其中一个配置 classifier

坑 7: 使用错误的发布插件 ❌

错误信息:

复制代码
Could not find artifact ... Failed to deploy artifacts

原因:

  • 使用了旧的 Nexus Staging 插件
  • 没有使用 Sonatype Central 官方推荐的插件

解决方案:

xml 复制代码
<!-- 使用 Sonatype Central 官方推荐的插件 -->
<plugin>
    <groupId>org.sonatype.central</groupId>
    <artifactId>central-publishing-maven-plugin</artifactId>
    <version>0.4.0</version>
    <extensions>true</extensions>
    <configuration>
        <publishingServerId>ossrh</publishingServerId>
        <tokenAuth>true</tokenAuth>
    </configuration>
</plugin>

💡 最佳实践

1. 构建顺序很重要 ⚡

bash 复制代码
# 使用 install 而不是 package,确保依赖被安装到本地仓库
mvn clean install -DskipTests

2. 环境变量设置 🔧

bash 复制代码
# 设置必要的环境变量
export GPG_TTY=$(tty)
export OSSRH_USERNAME=your_username
export OSSRH_PASSWORD=your_password
export GPG_PASSPHRASE=your_gpg_passphrase

3. 本地测试先行 🧪

bash 复制代码
# 先在本地测试部署
mvn clean install deploy -DskipTests -s settings.xml.template

4. 版本管理 📝

  • 使用语义化版本号
  • SNAPSHOT 版本用于测试
  • Release 版本用于正式发布

5. 文档和注释 📚

  • 在 pom.xml 中添加详细的项目信息
  • 配置正确的 SCM 和开发者信息
  • 添加许可证信息

🎉 成功发布后的验证

1. 检查 Sonatype Central

  • 登录 https://central.sonatype.com/
  • 查看你的 Namespace 下是否有新的 artifact
  • 检查发布历史记录
  • 确认 artifact 状态为 "Published"

2. 检查 Maven Central

  • 访问 https://search.maven.org/
  • 搜索你的 GroupId 和 ArtifactId
  • 注意:SNAPSHOT 版本可能不会出现在搜索结果中
  • 正式版本(如 1.0.0)会在搜索结果中显示

3. 测试依赖引用

xml 复制代码
<!-- 测试 SNAPSHOT 版本 -->
<dependency>
    <groupId>io.github.nemoob</groupId>
    <artifactId>simple-flow-api</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

<!-- 测试正式版本 -->
<dependency>
    <groupId>io.github.nemoob</groupId>
    <artifactId>simple-flow-api</artifactId>
    <version>1.0.0</version>
</dependency>

4. 验证发布成功

  1. 检查 artifact 文件

    • 确认 JAR 文件、源码 JAR、Javadoc JAR 都已上传
    • 检查 GPG 签名文件是否存在
  2. 测试下载

    bash 复制代码
    # 测试从 Maven Central 下载
    mvn dependency:get -Dartifact=io.github.nemoob:simple-flow-api:1.0.0
  3. 检查搜索索引

    • 等待 1-2 小时让搜索索引更新
    • 在 Maven Central 搜索中验证可见性

📊 发布流程图

否 否 否 否 本地开发 配置 pom.xml 配置 settings.xml 设置 GitHub Secrets 本地测试构建 本地测试部署 创建 GitHub Release 触发 GitHub Actions 构建和签名 部署到 Sonatype Central 同步到 Maven Central 验证发布成功 构建成功? 修复构建问题 部署成功? 修复部署问题 签名成功? 修复 GPG 问题 部署成功? 修复认证问题

🎯 总结

发布到 Maven Central 是一个需要耐心和细致的过程。主要注意点:

  1. 配置要完整 - pom.xml、settings.xml、环境变量都要正确配置
  2. 认证要正确 - Sonatype 账户、GPG 密钥都要正确设置
  3. 构建顺序要正确 - 多模块项目要按依赖顺序构建
  4. 测试要充分 - 先在本地测试,确保部署成功
  5. 文档要详细 - 项目信息、许可证、SCM 都要配置完整
  6. 使用正确的插件 - 使用 Sonatype Central 官方推荐的 central-publishing-maven-plugin
  7. 避免重复配置 - 确保插件配置不重复,避免冲突

🎉 成功案例

通过本文的指导,Simple Flow Framework 已经成功发布到 Maven Central!

通过本文的指导,你应该能够成功将项目发布到 Maven Central,让全球的开发者都能使用你的库! 🚀

相关推荐
孟婆来包棒棒糖~27 分钟前
Maven快速入门
java·spring boot·spring·maven·intellij-idea
jingfeng5143 小时前
C++模板进阶
java·c++·算法
ahauedu3 小时前
AI资深 Java 研发专家系统解析Java 中常见的 Queue实现类
java·开发语言·中间件
小厂永远得不到的男人4 小时前
基于 Spring Validation 实现全局参数校验异常处理
java·后端·架构
计算机编程小咖4 小时前
《基于大数据的农产品交易数据分析与可视化系统》选题不当,毕业答辩可能直接挂科
java·大数据·hadoop·python·数据挖掘·数据分析·spark
艾莉丝努力练剑4 小时前
【C语言16天强化训练】从基础入门到进阶:Day 7
java·c语言·学习·算法
老华带你飞5 小时前
校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园交友网站
沉迷技术逻辑5 小时前
Maven初识到应用
maven