發(fā)布了一個(gè)jar包到中央倉(cāng)庫(kù),我的心好累…
哈嘍大家好啊,我是Hydra。
前幾天我在網(wǎng)上沖浪的時(shí)候,看見(jiàn)有一個(gè)老鐵在git上給我提了一個(gè)issue:

萬(wàn)萬(wàn)沒(méi)想到,有一天我寫的爛代碼居然也會(huì)被要求提到中央倉(cāng)庫(kù)…
話再說(shuō)回來(lái),發(fā)布jar包到中央倉(cāng)庫(kù)這個(gè)事,也不是我不想,而是真的不會(huì)?。?/p>
不過(guò)既然鐵子們都開(kāi)口了,我這硬著頭皮也得上不是?那么從網(wǎng)上翻翻文檔,正式開(kāi)搞。
Sonatype
首先第一步,我們需要在sonatype上注冊(cè)賬號(hào)并提交一個(gè)issue。
sonatype這個(gè)名字,突然一說(shuō)大家可能有點(diǎn)反應(yīng)不過(guò)來(lái),但是看完下面這張圖大家應(yīng)該就明白了:

沒(méi)錯(cuò),如果各位所在的公司有搭建自己的maven私服的話,那么一般用的就是sonatype公司開(kāi)發(fā)的Nexus了。
這時(shí)候有小伙伴們估計(jì)就要問(wèn)了,那么我要上傳中央倉(cāng)庫(kù)和你sonatype又有什么關(guān)系?
這是因?yàn)閟onatype提供了一個(gè)服務(wù),英文全稱是Open Source Software Repository Hosting?,翻譯過(guò)來(lái)可以理解為開(kāi)源軟件資源庫(kù)托管服務(wù),簡(jiǎn)稱為OSSRH。
開(kāi)發(fā)者在把自己的開(kāi)源項(xiàng)目打成jar包后,可以免費(fèi)地將jar包托管在這里,這里先記住OSSRH這個(gè)簡(jiǎn)稱,后面很多地方還會(huì)用到。
并且,maven中央倉(cāng)庫(kù)是不允許我們直接上傳jar包到它上面的,因此我們只能將jar包發(fā)布到它指定的第三方maven倉(cāng)庫(kù),然后這個(gè)倉(cāng)庫(kù)再將jar包同步到中央倉(cāng)庫(kù)。而sonatype的OSSRH倉(cāng)庫(kù)就是被認(rèn)可的第三方倉(cāng)庫(kù)之一,所以我們選擇把jar包先發(fā)布到這上面來(lái)。
1、注冊(cè)
鋪墊了這么多,回過(guò)頭來(lái)注冊(cè)sonatype的賬號(hào),注冊(cè)地址:
https://issues.sonatype.org/secure/Signup!default.jspa
注冊(cè)比較簡(jiǎn)單,填一下郵箱、姓名、用戶名和密碼后,點(diǎn)擊sign up就完成了。

2、提交issue
登錄完成后,語(yǔ)言可以選擇中文,在system dashboard頁(yè)面中,點(diǎn)擊上方導(dǎo)航欄上的新建按鈕,就可以創(chuàng)建一個(gè)issue,我看也有地方把這個(gè)issue稱為工單。
要填的東西有點(diǎn)多,我們分兩頁(yè)看,先看第一頁(yè):

- 項(xiàng)目:選擇Community Support - Open Source Project Repository Hosting (OSSRH)
- 問(wèn)題類型:選擇New Project
- 概要:項(xiàng)目概要,這里填寫項(xiàng)目名稱就行,如果更嚴(yán)謹(jǐn)?shù)脑?,可以說(shuō)明是要新發(fā)布一個(gè)包到maven
- 描述:非必填項(xiàng),這里簡(jiǎn)單描述了一下項(xiàng)目的功能
填完這些后,接著填下面的內(nèi)容:

- Group Id?:項(xiàng)目的groupId?。如果以com?等開(kāi)頭的話,之后會(huì)驗(yàn)證你對(duì)該域名的所有權(quán)。所比較簡(jiǎn)單的做法是直接以io.github.?開(kāi)頭,再加上你的github的用戶名,所以這里我填寫的是io.github.trunks2008
- Project URL?:項(xiàng)目地址,不帶.git結(jié)尾
- SCM url?:也是項(xiàng)目地址,不過(guò)最后要帶上.git
- Username(s):非必填項(xiàng),這里是能輔助你提交項(xiàng)目的合作人的帳號(hào),前提是他也在這個(gè)JIRA注冊(cè)過(guò)賬號(hào)
- Already Synced to Central?:這里選擇No?,如果選Yes會(huì)關(guān)閉自動(dòng)同步到中央倉(cāng)庫(kù)
填寫完成后,點(diǎn)新建按鈕就完成了issue的提交。
3、創(chuàng)建臨時(shí)庫(kù)
創(chuàng)建完issue后等個(gè)幾分鐘,在它的活動(dòng)日志區(qū)就會(huì)收到一條回復(fù):

大意就是,如果想要繼續(xù)流程的話,就按照下面兩步走。
首先,先到你的github賬戶下面,按照它指定的名稱,建這么一個(gè)臨時(shí)倉(cāng)庫(kù),證明你對(duì)這個(gè)github賬號(hào)的所有權(quán)。于是我麻利的在github建好了這個(gè)倉(cāng)庫(kù):

然后問(wèn)題就來(lái)了,我們仔細(xì)看看回復(fù)中的第二步指南:
Edit this ticket and set Status to Open.
翻譯過(guò)來(lái)就是,編輯這個(gè)票據(jù)并把狀態(tài)設(shè)置為打開(kāi)狀態(tài)。
可就是這么樸實(shí)無(wú)華且枯燥的一句話,把我給難住了。在這條消息回復(fù)里,我把所有能點(diǎn)的地方點(diǎn)了一遍,也沒(méi)找到這個(gè)所謂的ticket是什么東西。
當(dāng)我的鼠標(biāo)都要點(diǎn)爛了時(shí),終于在別的老哥的提示下找到了答案,是要點(diǎn)擊這個(gè)issue中的這個(gè)毫不起眼的Respond按鈕??!

說(shuō)實(shí)話,在沒(méi)有人告訴我這是個(gè)按鈕之前,我一直以為這玩意就是一個(gè)破標(biāo)簽…
在我們把這個(gè)issue的狀態(tài)切換回Open后,過(guò)個(gè)幾分鐘,如果沒(méi)有其他問(wèn)題,那么你就會(huì)收到下一條回復(fù):

收到這條消息,就說(shuō)明我們的groupId已經(jīng)準(zhǔn)備好可以使用了,并且之后可以用當(dāng)前這個(gè)sonatype的賬號(hào)發(fā)布snapshot和release版本的jar包到它的oss倉(cāng)庫(kù)中了。
接著看下面一段,根據(jù)構(gòu)建配置,第一個(gè)組件可能會(huì)在成功部署(deploy)后自動(dòng)發(fā)布(release)。如果發(fā)生這種情況,那么我們會(huì)收到一條消息,來(lái)確認(rèn)我們的jar包被同步到了maven中央倉(cāng)庫(kù)。
既然人家都 congratulation 了,那咱們也開(kāi)心點(diǎn),到這里在sonatype上的操作就暫時(shí)告一段落了…
gpg秘鑰
接下來(lái),我們需要使用gpg生成秘鑰,在后續(xù)包發(fā)布jar時(shí)會(huì)根據(jù)生成的秘鑰進(jìn)行校驗(yàn),因?yàn)閟onatype也需要對(duì)上傳這一行為進(jìn)行權(quán)健的校驗(yàn),避免無(wú)意義或惡意上傳文件的行為。
1、安裝gpg
官網(wǎng)下載地址:
https://www.gnupg.org/download/
window版下載地址:
https://files.gpg4win.org/gpg4win-4.0.4.exe
我在下載了window版的安裝文件后,一路無(wú)腦點(diǎn)擊下一步就可以完成安裝了。
2、創(chuàng)建秘鑰
在安裝完成gpg后,在命令行下通過(guò)指令來(lái)生成一個(gè)秘鑰:
在生成的過(guò)程中,首先會(huì)要求輸入姓名和郵箱地址,在命令行窗口下填完這兩個(gè)信息后,還會(huì)彈窗要求輸入一個(gè)密碼:

這個(gè)密碼非常重要,一定要記住,后面在項(xiàng)目deploy的時(shí)候還會(huì)用到。填完后繼續(xù),秘鑰就會(huì)成功生成并保存在本地目錄下了:

3、上傳秘鑰
在秘鑰生成完后,我們需要把公鑰上傳到公共服務(wù)器供sonatype驗(yàn)證,可以通過(guò)下面的命令將公鑰上傳:
在公鑰上傳成功后,還可以通過(guò)--recv-keys來(lái)驗(yàn)證公鑰:

雖然我這里一次就上傳成功了,但是在看其他教程的過(guò)程中,也可能會(huì)出現(xiàn)失敗的情況,這種情況可以嘗試上傳到其他的存放公鑰的服務(wù)器:
- pool.sks-keyservers.ne
- keys.openpgp.org
- pgp.mit.edu
端口的話都是11371,這些公鑰服務(wù)器間會(huì)同步它們的數(shù)據(jù)給其他服務(wù)器,所以只要上傳成功到其中一臺(tái)就行。
maven 設(shè)置
接下來(lái)需要修改本地maven的配置,為了保險(xiǎn)起見(jiàn),我建議大家最好同時(shí)修改.m2和conf目錄下的配置文件,否則有可能出現(xiàn)一些奇怪的問(wèn)題。
1、server
首先在配置文件中添加一個(gè)server節(jié)點(diǎn),配置sonatype的用戶名及密碼:
2、profile
接著添加一個(gè)profie節(jié)點(diǎn),配置gpg信息,這里就需要填入在生成gpg秘鑰過(guò)程中,我們?cè)趶棿爸休斎氲拿艽a了:
在修改完成后,可以在命令行窗口下,通過(guò)命令查看我們修改過(guò)的配置是否已經(jīng)生效了:
如果顯示的內(nèi)容和配置文件中的一樣,那么恭喜,后面就只還剩下億點(diǎn)點(diǎn)工作了。
項(xiàng)目pom修改
在maven環(huán)境修改完成后,我們還需要對(duì)項(xiàng)目的pom文件進(jìn)行一些修改。
1、基礎(chǔ)信息
如果我們之前的代碼中,groupId?和sonatype上注冊(cè)的不一致,那么需要修改項(xiàng)目的groupId?改為一致。既然都要發(fā)布了,順便也把version改為release版本吧。
2、distributionManagement
添加distributionManagement信息,聲明要打包到sonatype的maven倉(cāng)庫(kù)中去。
3、plugins
這里需要添加各種plugin插件,除了常用的maven-compiler和maven-deploy插件外,還需要下面幾個(gè)關(guān)鍵插件:
- nexus-staging-maven-plugin: sonatype插件,用來(lái)將項(xiàng)目發(fā)布到中央倉(cāng)庫(kù)使用
- maven-source-plugin:生成java source.jar文件
- maven-javadoc-plugin:生成java doc文檔
- maven-gpg-plugin:對(duì)文件進(jìn)行自動(dòng)簽名
使用到的全部插件詳細(xì)配置如下,直接拷到項(xiàng)目中就可以使用:
至于在idea中,插件經(jīng)常下載失敗報(bào)紅線的問(wèn)題,個(gè)人測(cè)試可以先把它們加到dependencies中拉取下來(lái),成功率能高不少…
4、開(kāi)源簽名證書
添加license信息,使用Apache Licene 2.0 協(xié)議就行。
5、倉(cāng)庫(kù)信息
在這里填寫一下項(xiàng)目的地址,把我們的github倉(cāng)庫(kù)地址貼上去就可以了。
6、開(kāi)發(fā)人員信息
補(bǔ)充開(kāi)發(fā)者的個(gè)人信息,雖然估計(jì)也沒(méi)什么人會(huì)聯(lián)系我就是了。
在添加完這么多茫茫的信息后,我的pom文件成功的從70行變成了200多行……
發(fā)布
到這里所有的基本工作就都做完了,下面執(zhí)行激動(dòng)人心的deploy命令!
命令執(zhí)行結(jié)果:

果然是都到最后一步了,還是不能掉以輕心啊…
查了一下這個(gè)報(bào)錯(cuò),大概就是SSL的問(wèn)題,修改一下deploy命令的參數(shù)就行~
再次執(zhí)行命令:

奇怪的錯(cuò)誤又出現(xiàn)了…
這次的問(wèn)題比較簡(jiǎn)單,就是項(xiàng)目中的pom中缺失了一些項(xiàng)目信息,修改pom文件,添加下面的信息:
再次嘗試deploy,終于成功了!

登錄https://s01.oss.sonatype.org/,看一眼oss倉(cāng)庫(kù),我們的jar包已經(jīng)上傳成功了。

你以為到這里就結(jié)束了?恰恰相反,更加漫長(zhǎng)的等待才剛剛開(kāi)始…
漫長(zhǎng)的等待
在項(xiàng)目deploy成功后,回到sonatype,活動(dòng)日志區(qū)很快就會(huì)收到一條新消息:

大意就是sonatype到中央倉(cāng)庫(kù)的同步是激活的,當(dāng)我們成功發(fā)布組件后,通常30分鐘左右就可以在 https://repo1.maven.org/maven2/?上訪問(wèn)到了,但是更新到https://search.maven.org/可能需要4個(gè)小時(shí)。
按照這個(gè)提示,等半個(gè)小時(shí)再訪問(wèn)repo1.maven.org,經(jīng)過(guò)一路搜索最后可以找到:

過(guò)四個(gè)小時(shí)再訪問(wèn)search.maven.org,果然在上面也可以查找到我的jar包了,sonatype誠(chéng)不我欺…

講道理的話,既然發(fā)布成功了,那我們就可以在項(xiàng)目中按照這個(gè)maven坐標(biāo)拉取到j(luò)ar包了,但是在項(xiàng)目中就是死活拉不下來(lái)…
于是我靈機(jī)一動(dòng),改為使用gradle:
你別說(shuō),居然真的成功了…
不過(guò)話說(shuō)回來(lái),在日常工作中,我還是更習(xí)慣用https://mvnrepository.com來(lái)查找maven依賴,至于什么時(shí)候能在上面搜到,我實(shí)測(cè)了一下,這個(gè)周期真是長(zhǎng)的可怕。
在14號(hào)就上傳jar包成功后,直到17號(hào)才能在mvnrepository上查找到…

最后
那么,這次不那么順利的踩坑之旅到這里就基本上結(jié)束了,總的來(lái)說(shuō),發(fā)布jar包到中央倉(cāng)庫(kù)真是個(gè)體力活。
在實(shí)際操作的過(guò)程中,有著數(shù)不完的坑,動(dòng)不動(dòng)一個(gè)點(diǎn)就可能卡住好幾個(gè)小時(shí),即便成功發(fā)布了,后續(xù)還有漫長(zhǎng)的等待時(shí)間,總之就是非常心累…
對(duì)于那位在git上給我提issue的兄弟,我只有一句話想說(shuō)…
本文在sonatype上提交的issue,以及提交的項(xiàng)目git地址我都放在下面了,大家如果有需求的話,可以參考一下~
sonatype的issue地址:https://issues.sonatype.org/browse/OSSRH-86180
項(xiàng)目的github地址:https://github.com/trunks2008/ulquiorra-cache
官方文檔指南:https://central.sonatype.org/publish/publish-maven/





























