附录 1:🚀 Maven Central 发布完整指南:从零到成功部署

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

📋 目录

🎯 项目背景

项目:Simple Flow Framework

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

🔄 发布流程概览

graph TD A[准备阶段] --> B[Sonatype 账户设置] B --> C[GPG 密钥配置] C --> D[项目配置] D --> E[本地测试] E --> F[本地部署配置] F --> G[本地部署到 Maven Central] A --> A1[创建 Sonatype 账户] A --> A2[申请 GroupId] A --> A3[配置 GPG 密钥] D --> D1[更新 pom.xml] D --> D2[配置 settings.xml] D --> D3[设置环境变量] E --> E1[本地构建测试] E --> E2[GPG 签名测试] E --> E3[部署测试] F --> F1[设置环境变量] F --> F2[本地部署] F --> F3[验证发布]

📝 详细步骤

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 验证结果

central.sonatype.com/publishing/... 看到需要验证,点击 Publish,大概等待 5-10 分钟即可。

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

🐛 遇到的坑和解决方案

坑 1: 401 认证错误 ❌

错误信息:

vbnet 复制代码
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 签名失败 ❌

错误信息:

vbscript 复制代码
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 ❌

错误信息:

lua 复制代码
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 不匹配 ❌

错误信息:

lua 复制代码
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 生成失败 ❌

错误信息:

lua 复制代码
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 插件重复执行 ❌

错误信息:

vbscript 复制代码
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: 使用错误的发布插件 ❌

错误信息:

arduino 复制代码
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

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

2. 检查 Maven Central

  • 访问 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 搜索中验证可见性

📊 发布流程图

graph LR A[本地开发] --> B[配置 pom.xml] B --> C[配置 settings.xml] C --> D[设置 GitHub Secrets] D --> E[本地测试构建] E --> F[本地测试部署] F --> G[创建 GitHub Release] G --> H[触发 GitHub Actions] H --> I[构建和签名] I --> J[部署到 Sonatype Central] J --> K[同步到 Maven Central] K --> L[验证发布成功] E --> E1{构建成功?} E1 -->|否| E2[修复构建问题] E2 --> E F --> F1{部署成功?} F1 -->|否| F2[修复部署问题] F2 --> F I --> I1{签名成功?} I1 -->|否| I2[修复 GPG 问题] I2 --> I J --> J1{部署成功?} J1 -->|否| J2[修复认证问题] J2 --> J

🎯 总结

发布到 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,让全球的开发者都能使用你的库! 🚀

相关推荐
IT乐手3 小时前
Java 实现异步转同步的方法
java
渣哥3 小时前
Java HashMap 扩容机制详解:触发条件与实现原理
java
赵星星5203 小时前
Spring Bean线程安全陷阱:90%程序员都会踩的坑,你中招了吗?
java
Clownseven3 小时前
腾讯云远程桌面连接不上?5步排查法解决RDP连接失败
云计算·github·腾讯云
得物技术4 小时前
0基础带你精通Java对象序列化--以Hessian为例|得物技术
java·后端·编程语言
橘子在努力4 小时前
【橘子SpringCloud】OpenFegin源码分析
java·spring boot·spring·spring cloud
我是廖志伟4 小时前
JVM新生代Eden区域深度解析
java·jvm·memory management
十八旬4 小时前
苍穹外卖项目实战(day7-2)-购物车操作功能完善-记录实战教程、问题的解决方法以及完整代码
java·开发语言·windows·spring boot·mysql
BIGSHU09234 小时前
java多线程场景3-并发处理和异步请求
java·开发语言·python