V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NebulaGraph
V2EX  ›  推广

Dev 日志 | 如何将 jar 包发布到 Maven 中央仓库

  •  
  •   NebulaGraph · 2019-12-12 14:13:00 +08:00 · 454 次点击
    这是一个创建于 1811 天前的主题,其中的信息可能已经有所发展或是发生改变。

    摘要

    Maven 中央仓库并不支持直接上传 jar 包,因此需要将 jar 包发布到一些指定的第三方 Maven 仓库,比如:Sonatype OSSRH 仓库,然后该仓库再将 jar 包同步到 Maven ,本文详细记录整个发布、同步过程。

    注册一个 Sonatype 用户

    进入地址:https://issues.sonatype.org/secure/Signup!default.jspa 注册 Sonatype 用户,Sonatype 通过 JIRA ( JIRA 是 Atlassian 公司出品的项目与事务跟踪工具)来管理 OSSRH 仓库。

    创建一个发布构件的 issue

    提交「构件发布申请」的第一步是在 JIRA Dashborad 上创建一个 issue。如下所示,点击 Create 按钮:

    image

    会弹出一个对话框让你填写 issue 的详细信息,这里最重要的就是 Group Id,一般会带上域名,千万别弄错了,这关系到以后发布其它的构件。我们这里是com.vesoft

    Sonatype 有域名验证,验证方式:

    • 往你的 DNS 中添加 JIRA 编号记录
    • 重定向到你的 Github 主页

    如果你没有域名,可参考这个链接:http://central.sonatype.org/pages/choosing-your-coordinates.html 的方法进行操作

    • 选择一个带有项目托管信息的 GroupId,例如 io.github.facebook 或 com.github.facebook
    • 另外一种推荐的方式是使用免费的 free managed security reporting service

    等待 issue 审核通过

    审核因为时差原因需要一定时间,审核通过后会收到邮件通知,同时在对应 issue 下会看到 Sonatype 工作人员的回复,一般是添加一个 comment,内容大致如下:

    Configuration has been prepared, now you can: Deploy snapshot artifacts into repository https://oss.sonatype.org/content/repositories/snapshots Deploy release artifacts into the staging repository https://oss.sonatype.org/service/local/staging/ deploy/maven2 Promote staged artifacts into repository 'Releases' Download snapshot and release artifacts from group https://oss.sonatype.org/content/groups/public Download snapshot, release and staged artifacts from staging group https://oss.sonatype.org/content/groups/staging please comment on this ticket when you promoted your first release, thanks

    使用 GPG 生成密钥对

    生成密钥对

    > gpg --gen-key
    

    会让选择加密方式:

    • RSA and RSA (default)
    • DSA and Elgamal
    • DSA (sign only)
    • RSA (sign only)

    默认选第一个,选择之后,需输入用户名和邮箱,和 Passphase——相当于密钥库密码。

    查看公钥

    > gpg --list-keys
    
    xxx/.gnupg/pubring.gpg
    ---------------------------------
    pub   2048R/xxxx 2019-12-02
    uid   $YOUR_UID <$YOUR_EMAIL>
    sub   2048R/**** 2019-12-02
    

    这里的公钥 ID 是 xxxx,马上就会用到了。

    将公钥上传到 PGP 密钥服务器

    gpg --keyserver hkp://keys.gnupg.net:11371 --send-keys xxxx
    

    查看公钥是否上传成功

    > gpg --keyserver hkp://keys.gnupg.net:11371 --recv-keys xxxx
    
    gpg: 下载密钥‘xxxx’,从 hkp 服务器 keys.gnupg.net
    gpg: 密钥 xxxx:“$YOUR_UID <$YOUR_EMAIL>”未改变
    gpg: 合计被处理的数量:1
    gpg: 未改变:1
    

    NOTE:

    本地的私钥用来对上传的构件进行数字签名,而下载该构件的用户可通过上传的公钥来验证签名--需验证这个构件是否由本人上传的,因为存在构件被篡改的可能。

    修改 Maven 配置文件

    修改 Maven 配置文件主要是需要修改 setting.xml 和项目的 pom.xml 文件

    配置 Maven 的 setting.xml

    修改 ~/.m2/setting.xml 文件

    <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>snapshots</id>
                <username>$USER_NAME</username>
                <password>$YOUR_PASSWORD</password>
            </server>
            <server>
                <id>release</id>
                <username>$USER_NAME</username>
                <password>$YOUR_PASSWORD</password>
            </server>
        </servers>
    
    </settings>
    

    替换 USER_NAME , YOUR_PASSWORD 为 Sonatype 上面注册的用户名和密码, 这里的 ID 会在 pom.xml 里面使用到。

    配置 Maven 的 pom.xml

    <project>
        ...
    
        <!-- More Project Information -->
        <name>nebula-java</name>
        <description>Nebula Java Client</description>
        <url>https://github.com/vesoft-inc/nebula-java</url>
        <scm>
            <connection>scm:git:https://github.com/vesoft-inc/nebula</connection>
            <url>https://github.com/vesoft-inc/nebula</url>
            <developerConnection>scm:git:https://github.com/vesoft-inc/nebula</developerConnection>
        </scm>
        <licenses>
            <license>
                <name>Apache License, Version 2.0</name>
                <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
                <distribution>repo</distribution>
                <comments>license</comments>
            </license>
        </licenses>
    
        ...
        <profiles>
            <profile>
                <id>release</id>
                <build>
                    <plugins>
                        <!-- Source -->
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-source-plugin</artifactId>
                            <executions>
                                <execution>
                                    <id>attach-sources</id>
                                    <goals>
                                        <goal>jar</goal>
                                    </goals>
                                </execution>
                            </executions>
                        </plugin>
                        <!-- Javadoc -->
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-javadoc-plugin</artifactId>
                            <version>3.1.1</version>
                            <configuration>
                                <excludePackageNames>com.facebook.thrift:com.facebook.thrift.*</excludePackageNames>
                            </configuration>
                            <executions>
                                <execution>
                                    <id>attach-javadocs</id>
                                    <phase>package</phase>
                                    <goals>
                                        <goal>jar</goal>
                                    </goals>
                                    <configuration>
                                        <doclint>none</doclint>
                                    </configuration>
                                </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>
                    <repository>
                        <id>release</id>
                        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
                    </repository>
                    <snapshotRepository>
                        <id>snapshots</id>
                        <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
                    </snapshotRepository>
                </distributionManagement>
            </profile>
        </profiles>
        ...
    </project>
    
    • pom.xml 中必须包括: name 、 description 、 url 、 licenses 、 developers 、 scm 等基本信息 (~~血泪史之踩过的坑~~)
    • 发布 maven 除了 jar 必须还有文档包和源码包。因此 pom 需添加 maven-javadoc-plugin  和  maven-source-plugin 。 参考示例:
    com-vesoft-client
    |-- pom.xml
    |-- src\
    `-- target
        `-- attach-source-javadoc-1.0-SNAPSHOT.jar
        `-- attach-source-javadoc-1.0-SNAPSHOT-javadoc.jar
        `-- attach-source-javadoc-1.0-SNAPSHOT-sources.jar
    
    • 发布构建需要秘钥加密,因此 pom 需添加 maven-gpg-plugin  (~~血泪史之踩过的坑~~)

    多模块项目配置

    nebula-java 是多模块项目

    <modules>
        <module>client</module>
        <module>examples</module>
    </modules>
    

    为了上传 Client,需要上传 parent 的 pom.xml ,否则 Client 会找不到依赖(~~血泪史之踩过的坑~~),但我们又不希望上传 examples 模块,故做了如下改动:

    • 项目信息 namedescriptionurllicensesdevelopersscm 等信息和 maven-gpg-plugin 放在 parent 的 pom.xml 文件中
    <project>
      ...
        <name>nebula-java</name>
        <description>Nebula Java Client</description>
        <url>https://github.com/vesoft-inc/nebula-java</url>
        <scm>
            <connection>scm:git:https://github.com/vesoft-inc/nebula</connection>
            <url>https://github.com/vesoft-inc/nebula</url>
            <developerConnection>scm:git:https://github.com/vesoft-inc/nebula</developerConnection>
        </scm>
        <licenses>
            <license>
                <name>Apache License, Version 2.0</name>
                <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
                <distribution>repo</distribution>
                <comments>license</comments>
            </license>
        </licenses>
    
        <developers>
            <developer>
                <id>$ID</id>
                <name>$NAME</name>
                <email>$EMAIL</email>
                <organization>vesoft</organization>
                <roles>
                    <role>architect</role>
                    <role>developer</role>
                </roles>
            </developer>
        </developers>
    
        <distributionManagement>
            <repository>
                <id>release</id>
                <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
            </repository>
            <snapshotRepository>
                <id>snapshots</id>
                <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
            </snapshotRepository>
        </distributionManagement>
    
        <build>
            <plugins>
                <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>
      </project>
    
    • 在 Java Client 的 pom.xml 中添加 maven-javadoc-plugin  、  maven-source-plugin 和 maven-deploy-plugin
    <plugins>
      ......
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <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.1.1</version>
            <configuration>
                <excludePackageNames>com.facebook.thrift:com.facebook.thrift.*</excludePackageNames>
            </configuration>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <doclint>none</doclint>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <executions>
                <execution>
                    <id>default-deploy</id>
                    <phase>deploy</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
    

    在 example 模块的 pom.xml 中声明 skip deploy

    <plugins>
      ......
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>
    </plugins>
    

    Q: 为什么 maven-gpg-plugin 放在 parent 的 pom.xm l 中,而 maven-javadoc-pluginmaven-source-plugin 插件放在 Client 的 pom.xml 中

    A: 因为上传的所有构件都需要加密,包括 parent 的 pom.xml ,因此放在 parent 中; 而只有 Client 需要上传 javadoc,source,因此 maven-javadoc-pluginmaven-source-plugin 插件放在 Client 中。

    上传构件到 OSS 中

    在 nebula-java/ 目录下运行:

    > mvn clean deploy -DpomFile=pom.xml
    

    NOTE:不加 -DpomFile,上传的文件中会没有 parent 的 pom.xml (~~又是一部血泪史~~)

    在 OSS 中发布构件

    使用 Sonatype 账号登录 https://oss.sonatype.org/#stagingRepositories,可在 Staging Repositories  中查看已上传的构件,这些构件目前是放在 Staging 仓库中,可进行模糊查询,定位到刚上传的构件。

    此时,该构件的状态为 Open ,勾选它,然后点击 Close  按钮。系统会自动验证该构件是否满足指定要求 (幸福的人只有一种,不幸的人各有各的不幸,可能会遇到各种各样的不符合要求,Good luck !ヾ(◍°∇°◍)ノ゙)

    当验证完毕后,状态会变为 Closed

    image

    最后,点击 Release 按钮来发布该构件

    image

    页面可能要刷新一下才能看到最新的状态。

    通知 Sonatype 构件已成功发布

    在前面 JIRA 的 issue 下面回复一条“构件已成功发布”的评论,通知 Sonatype 的工作人员为要发布的构件做审批,发布后会关闭该 issue。

    等待构件审批通过

    然后,等待。。。

    从中央仓库中搜索构件

    大概十多分钟后,可以在这里 https://repo1.maven.org/maven2 找到刚刚发布的构件,可以直接在 pom.xml 中使用啦~~ 👏👏

    等同步完成大约 2 个小时,中央仓库(连接:http://search.maven.org/)就可以搜到啦。

    国内很多使用的是阿里云的镜像,镜像同步不是实时同步。为了及时使用,可以添加中央仓库镜像源,在 ~/.m2/setting.xml 文件添加,如下:

    <mirrors>
    ......
        <mirror>
            <id>nexus-mvn</id>
            <mirrorOf>central</mirrorOf>
            <name>Nexus Central</name>
            <url>http://repo1.maven.org/maven2</url>
        </mirror>
    </mirrors>
    

    第一次成功发布之后,以后就不用这么麻烦了,可以直接使用 Group Id 发布构件。

    后续操作

    之后同一个 Group Id 的发布流程

    最后温馨提示:发布的版本不支持修改,或者删除

    星云·小剧场

    为什么给图数据库取名 Nebula ? Nebula 是星云的意思,很大嘛,也是漫威宇宙里面漂亮的星云小姐姐。对了,Nebula 的发音是:[ˈnɛbjələ]

    本文星云图讲解--《阿尔普 188 和蝌蚪的尾巴》

    image

    为什么这个星系有这么长的尾巴?

    在这张令人惊叹的远景图中,根据哈勃遗留档案的图像数据,遥远的星系形成了一个引人注目的背景,这是被破坏的螺旋星系 Arp188,蝌蚪星系。

    宇宙蝌蚪距离北方的龙星座(天龙座)只有 4.2 亿光年。它引人注目的尾巴大约有 28 万光年长,以巨大、明亮的蓝色星团为特征。有一个故事是这样说的:一个更致密的闯入星系从 Arp 188 前穿过——从右到左——被它们的引力甩在蝌蚪后面。在这次近距离接触中,潮汐力将螺旋星系的恒星、气体和尘埃拉出,形成了壮观的尾巴。闯入者星系本身,估计位于蝌蚪后面 30 万光年处,可以通过右上角的前景螺旋臂看到。与地球同名的蝌蚪星系很可能会随着年龄的增长而失去尾巴,尾巴上的星团形成了大螺旋星系的小卫星。

    资料来源 | Hubble Legacy Archive, ESA, NASA;

    图片来源 | Astronomy Picture of the Day | 2018 December 11

    附录

    最后,附上 Nebula Graph GitHub 地址:https://github.com/vesoft-inc/nebula,如果你在使用 Nebula Graph 过程中遇到任何问题,欢迎 GitHub 联系我们或者加入微信交流群,请联系微信号:NebulaGraphbot

    关注公众号

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2739 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:34 · PVG 23:34 · LAX 07:34 · JFK 10:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.