如何發佈自己的項目到中央倉庫

来源:https://www.cnblogs.com/bryan31/archive/2020/07/19/13340695.html
-Advertisement-
Play Games

1 以前在github發開源項目,都因為懶,從來不構建到中央倉庫。最近因為其他人要用,聯繫我。希望可以發到中央倉庫。我想,不就是mvn deploy嘛,開搞。一圈弄下來,發現真沒那麼簡單。當中遇到了無數的坑,讓我每一次都心裡默默念到,發個項目,為何如此痛苦。 現將痛苦的過程詳細記錄下來。希望可以幫助 ...


1


以前在github發開源項目,都因為懶,從來不構建到中央倉庫。最近因為其他人要用,聯繫我。希望可以發到中央倉庫。我想,不就是mvn deploy嘛,開搞。一圈弄下來,發現真沒那麼簡單。當中遇到了無數的坑,讓我每一次都心裡默默念到,發個項目,為何如此痛苦。

現將痛苦的過程詳細記錄下來。希望可以幫助到其他小伙伴少踩點坑。

首先,你需要到sonatype這個站點上去註冊一個賬號。這個頁面長這個樣子:

file

我當時以為我進錯地方了,這不是jira嗎。好吧。看url還是提issue的地方,這和發佈項目有毛的關係...

好吧,點新建,項目選Community Support - Open Source,問題類型選New Project

file

填就是了。註意的是Group Id這裡要填你自己的擁有的功能變數名稱,比如com.xxxx,沒有的話,自己去註冊功能變數名稱去。填好之後就是等待審核。我搜了下,網上小伙伴說要等待3,5天。

3個小時後,我上去再去看,管理員給我回覆了:

file

大致意思就是要你證明這個功能變數名稱是屬於你自己的。有2種方法,加一個txt類型的解析到你的功能變數名稱里是最快的方法。

我的功能變數名稱申請在騰訊雲。登陸進去。找到功能變數名稱解析設置。加進去txt類型的解析。主機記錄填那個jira ticket名字,記錄值是你這個ticket的鏈接url。

file

設置完了後,去回覆管理員。然後繼續等待。

管理員大概很快就回覆了我。並通過了驗證。接下來,就要搗鼓項目了。

2


要上傳中央倉庫,你的項目必須要符合一些規範才行。

首先pom文件是有要求的,在你的項目頂層pom文件里一定要有以下標簽:

  • name
  • description
  • url
  • licenses
  • developers
  • issueManagement
  • scm

照著一個個填,我參考了一個開源項目的pom,例子如下:

<modelVersion>4.0.0</modelVersion>
<groupId>com.yomahub</groupId>
<artifactId>liteflow</artifactId>
<packaging>pom</packaging>
<version>2.2.0</version>
<name>liteflow</name>
<description>a lightweight and practical micro-process framework</description>
<url>https://github.com/bryan31/liteflow</url>
<licenses>
    <license>
        <name>MIT License</name>
        <url>https://opensource.org/licenses/MIT</url>
        <distribution>repo</distribution>
    </license>
</licenses>
<developers>
    <developer>
        <email>[email protected]</email>
        <name>bryan.zhang</name>
        <url>https://github.com/bryan31</url>
        <id>bryan31</id>
    </developer>
</developers>
<issueManagement>
    <system>Github Issue</system>
    <url>https://github.com/bryan31/liteflow/issues</url>
</issueManagement>
<scm>
    <connection>scm:[email protected]:bryan31/liteflow.git</connection>
    <developerConnection>scm:[email protected]:bryan31/liteflow.git</developerConnection>
    <url>[email protected]:bryan31/liteflow.git</url>
</scm>

補全了pom的信息後,還需要補全一些maven插件,主要有:

  • maven-source-plugin
  • maven-site-plugin
  • maven-javadoc-plugin
  • maven-gpg-plugin

例子如下:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <encoding>UTF-8</encoding>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <attach>true</attach>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-site-plugin</artifactId>
            <version>3.7.1</version>
        </plugin>
        <!-- Javadoc -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.0.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Gpg Signature -->
        <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>

當然還需要加上distributionManagement

<distributionManagement>
		<snapshotRepository>
			<id>sonatype</id>
			<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
		</snapshotRepository>
		<repository>
			<id>sonatype</id>
			<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
		</repository>
</distributionManagement>

你的sonatype的用戶名和密碼當然不能寫在項目pom里,你得在maven的setting.xml里添加server

<server>
    <id>sonatype</id>
    <username>your username</username>
    <password>your password</password>
</server>


3


補全了pom的一些規定信息和插件後。可以試下是否可以正確無誤的生成javadoc,在項目根目錄下運行

mvn site

接下去就是無盡的等待,等待從中央倉庫下載各種插件。這裡最好搭個梯子翻牆,速度會快點。我全程用梯子,也等了40分鐘,這時候可以去乾點別的事情。。40分鐘後,終於build成功了:

file

接下去就是簽名了。想要上傳到倉庫,jar包必須被正確簽名。

用gpg來進行簽名,網上搜了下,windows的用戶可下載gpg4win,我這裡用的是mac,不能用這個軟體。只能自己安裝個命令行gpg工具了

brew install gpg

安裝成功後,執行命令生成秘鑰對:

gpg --gen-key

根據提示,填寫用戶名和郵件地址。然後確認。

我mac上用的是iterm2,確認後一直卡著,提示正在生成位元組。然後等了很久也沒有反應。我一直以為這就是正常現象,已經生成秘鑰對了。只不過命令行不友好,沒有告訴我。。。導致了我後面簽名一直簽不成功。

後來我換了一個ssh工具,electerm,才正確生成。最後是要讓你輸入passphase。以下是正確生成秘鑰對的界面

file

接下去就是要利用maven-gpg-plugin對jar包進行簽名了。在進行之前,需要在setting.xml文件的當前profile裡加上

<properties>
    <gpg.executable>gpg</gpg.executable>
    <gpg.passphrase>your passphrase</gpg.passphrase>
</properties>

然後運行mvn install。

我這裡一直簽名不成功,報以下錯:

file

網上搜索了下,原來是我本地的gpg工具版本太新了,和maven的插件版本不匹配。需要在~/.gnupg這個目錄下增加2個配置:

gpg.conf

use-agent
pinentry-mode loopback

gpg-agent.conf

allow-loopback-pinentry

折騰了半天,終於可以mvn install正確執行gpg的jar包簽名了。接下去準備進行激動人心的mvn deploy了。

由於之前已經解決了jar包簽名的問題,deploy過程也是相當的順利。deploy過程中,會把你項目的jar包,加簽信息,javadoc,javasource等包一併上傳到sonatype伺服器。

deploy好,你就可以在sonatype的staging repo里看到了,staging repo相當於暫存的狀態,還沒有正式發佈到release倉庫,sonatype需要校驗你上傳jar包的規範性,合法性。

選中你提交的暫存信息,點close,等一段時間,refresh之後底下會有校驗結果。全部通過後才能點release。底下是我第一次校驗的結果:

file

可以看到,有2項沒通過,第1項是我pom不規範,原因是我第一次pom提交的時候少了<name>標簽。關鍵是第2項簽名校驗失敗,從右邊的詳細信息里可以看到,sonatype在校驗我的jar包簽名時找不到我的public key。

gpg生成的是RSA的key,有公鑰和私鑰。我本地加簽之後,應該把公鑰給到sonatype,否則sonatype無法驗證我的jar包的加簽信息是否有效。所以我之前流程應該缺少了這一步!

看詳細信息,sonatype應該是到以下3個地方去拿key,發現都沒有,所以才報了錯。

http://pgp.mit.edu:11371
http://keyserver.ubuntu.com:11371
http://pool.sks-keyservers.net:11371

所以我們只需要上傳key到任意一個key server就可以了。

gpg上傳公鑰的命令是

gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys yourkeyid

這裡我踩了2個坑,第一個是上傳的協議是hkp,不是http,網上一搜才知道。sonatype報錯的地方都是http。

第二個是gpg在發送公鑰的時候並不是直接指定公鑰發上去,而是需要你的keyid,個人推測可能是根據這個keyid再在文件系統中找到公鑰進行發送吧。它需要什麼,我們只能給什麼。問題是這個keyId是什麼呢,從哪來呢

在生成秘鑰對的時候,我註意到給了一個fingerprint,也能用gpg --list-keys 這個命令進行查看:

file

難道這個就是keyId?我嘗試著用這個作為keyId,進行發送,也能成功。但是在sonatype上進行檢測卻過不了。

這個keyId卡了我很久,最後還是依靠萬能的谷歌查到了。原來所謂的KeyId就是fingerprint的後16個字元。我Fxx...(省略N個贊美的詞語)。

拿到了正確的KeyId,繼續執行gpg的上傳命令,上傳好,然後運行查看key的命令:

gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys yourkeyid

也能在key server上找到

file

4


我們繼續在sonatype的staging repo進行close操作校驗,這個操作其實我已經做了n遍了,各種坑,所以見到以下這個畫面的時候有點激動:

file

可以看到,所有的校驗都通過了,沒有報錯了。Release的按鈕也已經點亮。通往中央倉庫的大門已經敞開!

堅定的點下release按鈕。輸入備註後,成功提交。

在sonatype進行Release後 ,要真正在中央倉庫看到,可能要等上個5到6小時。

最後。終於,在中央倉庫的地址我看到了提交的包,大功告成

file

原本以為提交中央倉庫可能不是那麼困難,實際操作一遍,發現需要註意的細節有很多。而項目本身也有很多需要規範的地方。整個過程花了一天時間,碰了無數的坑,我工位旁邊的小伙伴之前操作過,但是時間久遠,細節又很多。所以對很多坑印象比較模糊了。所以記錄下來。

個人開發的項目被其他人所使用,是一件很有成就感的事情。所以提交中央倉庫是必然途徑。雖然我希望整個過程能簡單點,但是中央倉庫就一個,只能按照它的規範來做。希望有人看到這篇記錄,能讓你少走點彎路~

5

微信關註 「jishuyuanren」獲取更多技術乾貨


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 面對可能出現的網路延遲,不可預估的請求流量等情況,設計一個分散式系統,我們通常圍繞系統高可用,數據一致性的目標去規劃和實現,想要完全實現這個目標,卻並非易事。由此,分散式系統領域誕生了一個基本定理,即 CAP 定理,用於指導分散式系統的設計,從系統高可用,數據一致性,網路容錯三個角度將分散式系統的特 ...
  • 在已知的可直接作用於for迴圈的數據類型有以下幾種 第一類 list tuple dict set str 第二類 generator 可直接作用於for迴圈的對象統稱為可迭代對象:Iterable 可利用 isinstance() 判斷一個對象是否是 Iterable 對象 from collec ...
  • 網上關於Spring迴圈依賴的博客太多了,有很多都分析的很深入,寫的很用心,甚至還畫了時序圖、流程圖幫助讀者理解,我看了後,感覺自己是懂了,但是閉上眼睛,總覺得還沒有完全理解,總覺得還有一兩個坎過不去,對我這種有點笨的人來說,真的好難。當時,我就在想,如果哪一天,我理解了Spring迴圈依賴,一定要 ...
  • 關於編程語言中的註釋,其重要性基本上已為大家所共識。 然而關於註釋的規範,這個話題就像我們之前聊過的縮進、終止符和命名方式一樣,眾口難調。 註釋符通常可分為兩種,即行註釋與塊註釋(inline/block),它們在不同的編程語言中的符號可謂讓人眼花繚亂。 比如行註釋符,它至少有以下的 17 種之多( ...
  • 第十四章 高級函數 14.1重載成員函數 ​ 函數可以進行重載,成員函數(成員方法)實質上也是一種函數,所以成員函數也可以進行重載。 程式清單14.1 Rectangle.cpp #include <iostream> class Rectangle { private: int width; in ...
  • 在寫這篇文章時,我是滿懷感激與賞識之情的。 來誇一個人,講一個道理,寫給大家,也是寫給自己。 來自讀者的反饋 先說說事情的經過。 新書出版之後,昨天第一次看到(抱歉看到的比較晚)讀者的反饋。所謂反饋就是在書中留了GitHub的地址,如果書中有錯誤的地方,讀者可以通過該鏈接提交Issues(問題),來 ...
  • 之前只是很模糊的知道其意思:在request scope中,每個request創建一個新的bean;在session scope中,同一session中的bean都是一樣的。但是不知道怎麼用代碼去驗證它,今天可找到驗證它的代碼了。 ...
  • 隊列實質就是一種存儲數據的結構 通常用鏈表或者數組實現 一般而言隊列具備FIFO先進先出的特性,當然也有雙端隊列(Deque)優先順序隊列 主要操作:入隊(EnQueue)與出隊(Dequeue) BlockingQueue 隊列實質就是一種存儲數據的結構 通常用鏈表或者數組實現 一般而言隊列具備FI ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...