天天看點

将你自己的項目釋出到maven中央倉庫為什麼寫這篇文章什麼是maven中央倉庫釋出到中央倉庫的好處釋出過程

為什麼寫這篇文章

現在OkHttp很火,研究學習了一下,鋪天蓋地的教程和通用工具都是Android用的,封裝了很多Android的元件在裡邊.但是OkHttp不是一個安卓庫啊,它是java庫,所有基于JVM的語言都可以用.

是以自己寫了個OkHttp通用簡單封裝并放到了github,這是本人第一個開源項目,有點小興奮呢.但是隻是開源,别人想使用也麻煩,還要下載下傳下來自己編譯,然後就想到了把它送出到maven中央倉庫.但是沒有送出過啊,各種搜尋折騰了一天,終于成功了.

這篇文章大概介紹一下如何将自己的項目釋出到maven中央倉庫及我滾過的坑(可能大家會覺得可笑,想笑就笑吧,反正我也看不見o(∩_∩)o )

什麼是maven中央倉庫

偷個懶,下面的内容摘抄自 釋出項目到maven中央倉庫

maven是java世界最流行的建構工具,建構内容囊括了一個java項目的整個生命周期。其中最重要的功能就是依賴管理,maven通過一個類似雲的ftp站點統一管理所有java 的jar檔案,同時給每個檔案的每個版本一個統一的唯一坐标。開發人員通過檢索配置這些坐标,選擇自己需要的構件搭建自己的項目環境。是以,通過一個叫做pom的描述檔案,我們就可以在任何平台搭建好項目運作所需要的環境。友善了協作和分享代碼。
而那個類似雲的ftp站點就是maven中央倉庫。由于一些不可抗拒因素,我們對于中央倉庫的通路速度比較慢。是以在平時工作環境中,我們往往都是使用一些鏡像站點,如阿裡雲和開源中國的倉庫鏡像。同時由于公司裡的商業代碼不可釋出到公開站點,我們也會在區域網路内搭建私服。但是無論是鏡像還是私服,都像是緩存,雖然提高了下載下傳速度,但是最終,所有的jar都來自中央倉庫。是以,如果我們将項目釋出到了maven 中央倉庫中,那麼在所有基于maven或者gradle等的項目裡都可以依賴下載下傳你的構件。真正做到了一次釋出,處處可用。

釋出到中央倉庫的好處

偷個懶,下面的内容摘抄自 釋出項目到maven中央倉庫

首先,作為一個java從業者,對于天天都在用的東西,做一個深入的了解,釋出一個項目到中央倉庫可以自我滿足。作為我來講,我釋出了一個自己的項目,開始有了利用下班時間好好寫點開源代碼學習和裝逼的沖動。
再者,作為一個經驗豐富的java開發工程師,我們在日常工作中總會積攢下自己使用得很順手的一些輪子或者一些通用的基礎類。如果我們整理好,并持續維護,釋出到了中央倉庫之後,就可以避免很多重複性的工作。而且也避免了很多沖突:我現在的公司裡,每個項目的dubbo調用接口都會自己定義一個Response和Request類。同一類型的重複定義,跟cpp的多根繼承一樣煩。這樣的結果導緻了沒法統一處理各個系統的調用傳回值。既不夠優雅,也顯得重複。如果我們把這些基礎的東西釋出到了中央倉庫,就隻需要引用一下了。當然這種情況一般是釋出到私服比較好,我隻是舉個例子。具體的大家自行體會。

釋出過程

在釋出前,您需要有自己的項目首頁并開源的代碼,您可以使用GitHub或者碼雲,下面的内容以GitHub為例

注冊 sonatype的Jira 帳号

注冊位址: https://issues.sonatype.org/secure/Signup!default.jspa

注冊很簡單,重要的是郵箱位址一定要正确,issue有任何變動都會通過郵件通知.

這裡要着重說明一下,也是我滾過的坑: Username 字段一定要使用英文+數字,一定不要使用中文!!!否則官方無法配置設定權限給你,或者會讓你另行注冊.

因為這個Username會成為這個Jira和送出maven項目的OSS的帳号,雖然用中文登入啥的沒問題,但送出的時候就有問題了,我折騰了N個小時,最後又求助官方人員才解決.

我當時發了一個issue,就叫 issues1吧,當時官方人員讓我修改GroupId,修改後我回複修改完成,等了好多個小時都沒回應.然後我又送出了一個issue2,内容與issue1一毛一樣,很快就有官方人員說OK了.

沒過幾分鐘issue1也有官方人員回複了(不是一個人),說我的帳号XX(中文) 不行,讓我重新注冊一個帳号再回複,他幫我弄.

由于當時issue2已經有官方人員回複OK了,我就在issue1裡回複說我在另一個issue裡已經解決.然後我就很歡喜的去送出,折騰了好久都沒送出上,一直說沒有權限...但是當時我用那個帳号登入OSS是可以登入的,就是送出不了.

折騰了幾個小時之後,很無奈的去issue2裡求助官方人員,然後在issue1裡讓我重新注冊的兄弟在issue2裡說是因為我的帳号是中文,無法配置設定權限,讓我重新注冊一個再在issue2裡回複,他幫我配權限...

重新注冊了一個帳号之後,用新的帳号送出,OK了...

登入Jira

注冊完成後就登入: https://issues.sonatype.org/login.jsp

建立一個 Issue

建立位址: https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134

這個位址已經選擇好了項目和類型,直接填就行,當然,如果你要通過【Create】按鈕建立

Project選擇【Community Support - Open Source Project Repository Hosting (OSSRH)】

Issue TypeRequired選擇【New Project】

Summary,Description 自己填,注意要用E文

Group Id: 這個必須要注意,如果你用的是GitHub, 一定要是 com.github.你的github使用者名, 例如我的項目位址是: https://github.com/KeRan213539/CommonOkHttp, 那我的 groupId就是com.github.KeRan213539,當然也可以使用 GitHub的Page的域名 io.github.你的github使用者名. 如果你有自己的域名和項目位址也可以,官方人員會詢問你是否有這個域名的所有權.在你項目的pom裡一定要使用這個groupId,最好包路徑也使用

Project URL: 是你的項目位址

SCM url: 是你的項目git位址

Username(s): 可以不用填,這是能輔助你送出項目的合作人的帳号,前提是他也得在這個Jira注冊

其他使用預設值就行了

建立好Issue後就等待官方回複吧.通常如果在晚上22點23點的話回複會比較快,運氣好幾分鐘就有回複了

當看到回複類似 com.github.xxx has been prepared, now user(s) xxx can:Deploy snapshot artifacts into repository ... 說明OK了,可以送出了

使用 GPG 生成密鑰對

在等待Issue的時候可以先把密鑰搞好

Windows 系統,可以下載下傳 Gpg4win 軟體來生成密鑰對。下載下傳位址:https://www.gpg4win.org/download.html

下載下傳的時候有個坑,會彈出一個捐助頁面,然後沒有下載下傳的地方,也沒有自動開始下載下傳.感覺好像不捐助就不能下載下傳一樣.其實在下載下傳頁面下面有個All Downloads,裡面有個連接配接files.gpg4win.org,在這裡找到與下載下傳頁面上的最新版相同的版本号下載下傳即可

安裝過程中在選擇元件的時候,除了預設必須安裝的,其他取消即可

安裝完成後,打開CMD

檢視是否安裝成功

gpg --version

生成密鑰對

gpg --gen-key

Real name: 名字(E文)

Email address: 郵箱

You selected this USER-ID:

"xxx[email protected]"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? o

之後往下,會讓你輸入使用者名和郵箱,還有一個Passphase(輸入兩次),相當于密鑰庫密碼,不要忘記。

檢視公鑰

gpg --list-keys

pub rsa2048 2017-12-16 [SC] [expires: 2019-12-16]

9DF36BF5DFB87B6F04DBCE3D63EC6544BEE6682D

uid [ultimate] xxx[email protected]

sub rsa2048 2017-12-16 [E] [expires: 2019-12-16]

其中 9DF36BF5DFB87B6F04DBCE3D63EC6544BEE6682D 就是公鑰

将公鑰釋出到 PGP 密鑰伺服器

gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 你的公鑰

查詢公鑰是否釋出成功

gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 你的公鑰

修改Maven配制

如果你的Issue通過了,那麼可以開始送出項目了.

修改maven全局配制檔案 settings.xml,在maven安裝目錄的conf檔案夾下

<servers>

<server>

<id>oss</id>

<username>使用者名</username>

<password>密碼</password>

</server>

</servers>

這裡的 id 是要在 pom.xml 裡面使用的,使用者名和密碼就是Jira的帳号密碼

pom.xml
<project>
    ...
    <name>dexcoder-assistant</name>
    <description>dexcoder-assistant is a rapid development kit.</description>
    <url>http://www.dexcoder.com/</url>
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>
    <developers>
        <developer>
            <name>selfly</name>
            <email>[email protected]</email>
        </developer>
    </developers>
    <scm>
        <connection>scm:git:[email protected]:selfly/dexcoder-assistant.git</connection>
        <developerConnection>scm:git:[email protected]:selfly/dexcoder-assistant.git</developerConnection>
        <url>[email protected]:selfly/dexcoder-assistant.git</url>
    </scm>
    
    <profiles>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <!-- Source -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-source-plugin</artifactId>
                        <version>2.2.1</version>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>jar-no-fork</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- Javadoc -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <version>2.9.1</version>
                        <configuration>
                            <show>private</show>
                            <nohelp>true</nohelp>
                <charset>UTF-8</charset>
                <encoding>UTF-8</encoding>
                <docencoding>UTF-8</docencoding>
                <additionalparam>-Xdoclint:none</additionalparam>  <!-- TODO 臨時解決不規範的javadoc生成報錯,後面要規範化後把這行去掉 -->
            </configuration>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>jar</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- GPG -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-gpg-plugin</artifactId>
                        <version>1.5</version>
                        <executions>
                            <execution>
                                <phase>verify</phase>
                                <goals>
                                    <goal>sign</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <distributionManagement>
                <snapshotRepository>
                    <id>oss</id>
                    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
                </snapshotRepository>
                <repository>
                    <id>oss</id>
                    <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
                </repository>
            </distributionManagement>
        </profile>
    </profiles>
    ...
</project>
           

pom.xml 中必須包括:name、description、url、licenses、developers、scm 等基本資訊,使用了 Maven 的 profile 功能,隻有在 release 的時候,建立源碼包、文檔包、使用 GPG 進行數字簽名。

此外,snapshotRepository 與 repository 中的 id 一定要與 setting.xml 中 server 的 id 保持一緻。

如果是多子產品項目的話,隻需要在父 pom.xml 中聲明這些,子 pom.xml 中隻需要修改相應的一些資訊,如 name 标簽。

由于我使用的是jdk8,對doc的格式要求更嚴,不标準的doc注釋會報錯,這時候可以通過在doc插件中配制additionalparam參數,上面代碼裡已經配過了.但這隻是臨時解決方案,還是盡量使用标準的doc注釋吧.

送出項目到OSS

maven配制修改完成後,就可以送出項目了,使用指令:

mvn clean deploy -P release
           

當執行以上 Maven 指令時,會自動彈出一個對話框,需要輸入上面提到的 Passphase,它就是剛才設定的 GPG 密鑰庫的密碼。

注意:此時上傳的構件并未正式釋出到中央倉庫中,隻是部署到 OSS 中了,下面才是真正的釋出。

執行上面的指令的過程中,可能會找不到gpg.exe, 檢查環境變量,發現環境變量中已經配制了gpg.exe所在的路徑,但是還是報錯... 如何解決? setting.xml中加入:
<profile>
      <id>release</id>
      <properties>
        <gpg.executable>D:/Program Files (x86)/GnuPG/bin/gpg.exe</gpg.executable>
        <gpg.passphrase>上面提到的 Passphase</gpg.passphrase>
      </properties>
    </profile>
                

注意 ID要與pom.xml裡的釋出的 profile 的ID對應

其中<gpg.executable>為你的gpg.exe的完整路徑

<gpg.passphrase> 為上面提到的 Passphase,這樣就不用在每次釋出的時候都輸入密碼了,但是我發現即便有這個,有時候(隻是有時,不是每次)還是要讓輸入密碼,暫時不清楚是什麼問題.

上面這2個配制也可以配制到pom.xml的gpg插件的<configuration>中,去掉<gpg.>就行,當然密碼最好還是不要放在pom.xml裡,因為如果你的代碼開源的話,密碼也一起開源了...

如何釋出快照版本?

在pom.xml中的項目版本号後面加上 -SNAPSHOT 就行

在 OSS中釋出

使用 Jira 賬号登入 https://oss.sonatype.org,在 Staging Repositories 中檢視剛才已上傳的構件。

一般釋出的構件不多,可以直接滾動條拉到最後就能看到自己的構件,或者更改時間排序,也可進行模糊查詢定位到自己的構件

找到自己的建構後選中,并點選上方的 【Close】按鈕關閉建構,這個過程有點慢,稍等幾分鐘

重新整理頁面,發現關閉成功後,再次選中自己的建構,點選上方的【Release】釋出建構.

通知Sonatype 已經成功釋出

在Issue中通過稽核的官方回複中,通常會讓你在釋出成功後再次回複告知他們,在剛才那個Issue中回複已經成功釋出,官方會回複你大概需要等多久才能在中央倉庫中找到你的項目(10分鐘左右)以及要多久才能在搜尋中搜到(2個小時左右)

以後的送出過程

第一次送出才這麼麻煩,以後送出隻用重複maven釋出,OSS中Close,Release的過程就可以了,當然需要等待的時間還是10分鐘和2小時.

如果要釋出新的項目,在使用相同GroupId的情況下,與上面的過程一樣.隻有使用不同的GroupId的時候,才會需要再去送出Issue申請.

當然如果你沒有換電腦的話 GPG 的過程隻需要一次就行

結束

到此釋出過程就結束了.本文參考了以下文章,特别感謝這些文章的作者:

Maven 釋出自己的項目到 Maven 中央倉庫

[幹貨]--釋出項目到maven中央倉庫

将項目釋出到Maven中央庫