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

来源: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
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...