1. 程式人生 > >如何釋出Maven依賴到中央倉庫

如何釋出Maven依賴到中央倉庫

平時我們都是從Maven中央倉庫下載依賴,如果我們想釋出我們自己寫的Maven依賴到中央倉庫供別人下載使用應該怎麼辦?這裡以上傳自己寫的simian-maven-plugin(https://github.com/jiangxincode/simian-maven-plugin)的實際過程為例說明如何釋出Maven依賴到中央倉庫。

開始之前,請注意幾個地址: 

1、工單管理:https://issues.sonatype.org/secure/Dashboard.jspa

說明:註冊賬號、建立和管理issue,依賴的釋出是以解決issue的方式起步的。

2、快取倉庫:https://oss.sonatype.org/#stagingRepositories

說明:當我們釋出非SNAPSHOT版本時,會先將依賴上傳到該過渡倉庫,之後才能正式釋出到中央倉庫。

建立工單

訪問工單管理的網址:https://issues.sonatype.org/secure/Dashboard.jspa

如果之前沒有註冊過sonatype賬號,需要先註冊一個賬號,註冊過程本文不在贅述,務必記住使用者名稱和密碼。 

 

Create Issue 填寫內容說明: 

===Step 1===

Project:Community Support - Open Source Project Repository Hosting

Issue Type:New Project

===Step 2===

Summary:依賴名稱,如:simian-maven-plugin

Group Id:對應你的依賴的groupId,如com.github.jiangxincode

Project URL:專案站點,如:https://github.com/jiangxincode/simian-maven-plugin

SCM url:專案原始碼倉庫,如:https://github.com/jiangxincode/simian-maven-plugin.git

 

其他內容不用填寫,建立Issue後需要等待一小段時間,Sonatype的工作人員稽核處理,速度還是很快的,一般一個工作日以內,當Issue的Status變為RESOLVED後,就可以進行下一步操作了。

 

 

配置pom.xml

在工程的pom.xml檔案中,引入Sonatype官方的一個通用配置oss-parent,這樣做的好處是很多pom.xml的釋出配置不需要自己配置了:

<parent>

<groupId>org.sonatype.oss</groupId>

<artifactId>oss-parent</artifactId>

<version>7</version>

</parent>

 

並增加Licenses、SCM、Developers資訊:

<licenses>

<license>

<name>The Apache Software License, Version 2.0</name>

<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>

<distribution>repo</distribution>

</license>

</licenses>

<scm>

<tag>master</tag>

<url>[email protected]:jiangxincode/simian-maven-plugin.git</url>

<connection>scm:git:[email protected]:jiangxincode/simian-maven-plugin.git</connection>

<developerConnection>scm:git:[email protected]:jiangxincode/simian-maven-plugin.git</developerConnection>

</scm>

<developers>

<developer>

<name>Aloys</name>

<email>[email protected]</email>

<organization>Github</organization>

</developer>

</developers>

 

修改maven配置檔案settings.xml,在servers中增加server配置。

<servers>

<server>

<id>sonatype-nexus-snapshots</id>

<username>Sonatype 賬號</username>

<password>Sonatype 密碼</password>

</server>

<server>

<id>sonatype-nexus-staging</id>

<username>Sonatype 賬號</username>

<password>Sonatype 密碼</password>

</server>

</servers>

 

配置gpg-key

首先需要使用gpg工具生成一對金鑰,以Windows為例,如果你安裝了Git(https://git-scm.com/)則已經有了gpg工具,如果沒有可以單獨下載gpg4win(https://www.gpg4win.org/download.html)。以Git自帶的gpg工具為例,生成金鑰方式如下:

[email protected] MINGW64 /d/temp/Java/simian-maven-plugin (master)

$ gpg --gen-key

gpg (GnuPG) 1.4.22; Copyright (C) 2015 Free Software Foundation, Inc.

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.

   

gpg: directory `/c/Users/jiang/.gnupg' created

gpg: new configuration file `/c/Users/jiang/.gnupg/gpg.conf' created

gpg: WARNING: options in `/c/Users/jiang/.gnupg/gpg.conf' are not yet active during this run

gpg: keyring `/c/Users/jiang/.gnupg/secring.gpg' created

gpg: keyring `/c/Users/jiang/.gnupg/pubring.gpg' created

Please select what kind of key you want:

(1) RSA and RSA (default)

(2) DSA and Elgamal

(3) DSA (sign only)

(4) RSA (sign only)

Your selection?

RSA keys may be between 1024 and 4096 bits long.

What keysize do you want? (2048)

Requested keysize is 2048 bits

Please specify how long the key should be valid.

0 = key does not expire

<n> = key expires in n days

<n>w = key expires in n weeks

<n>m = key expires in n months

<n>y = key expires in n years

Key is valid for? (0)

Key does not expire at all

Is this correct? (y/N) y

   

You need a user ID to identify your key; the software constructs the user ID

from the Real Name, Comment and Email Address in this form:

"Heinrich Heine (Der Dichter) <[email protected]>"

   

Real name: Aloys

Email address: [email protected]

Comment: for sonatype

You selected this USER-ID:

"Aloys (for sonatype) <[email protected]>"

   

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

Comment: JiangXin

You selected this USER-ID:

"Aloys (JiangXin) <[email protected]>"

   

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

You need a Passphrase to protect your secret key. **********

   

We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

........+++++

...........+++++

We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

.+++++

+++++

gpg: /c/Users/jiang/.gnupg/trustdb.gpg: trustdb created

gpg: key 2AB935A0 marked as ultimately trusted

public and secret key created and signed.

   

gpg: checking the trustdb

gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model

gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u

pub 2048R/2AB935A0 2018-10-28

Key fingerprint = A5C1 8750 A311 0057 671C D8B7 A14C A7F2 2AB9 35A0

uid Aloys (JiangXin) <[email protected]>

sub 2048R/94B6D362 2018-10-28

 

過程中需要填寫名字、郵箱等,其他步驟可以使用預設值,其中需要出入Passphase,這個相當於是是金鑰的密碼,請務必記住該密碼,之後釋出過程中會用到。 操作之後開啟命令列視窗,檢視gpg key並上傳到第三方的key驗證庫:

[email protected] MINGW64 /d/temp/Java/simian-maven-plugin (master)

$ gpg --list-keys

/c/Users/jiang/.gnupg/pubring.gpg

---------------------------------

pub 2048R/2AB935A0 2018-10-28

uid Aloys (JiangXin) <[email protected]>

sub 2048R/94B6D362 2018-10-28

   

   

[email protected] MINGW64 /d/temp/Java/simian-maven-plugin (master)

$ gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys 2AB935A0

gpg: sending key 2AB935A0 to hkp server keyserver.ubuntu.com

 

 

 

部署依賴到stagingRepositories

執行如下命令部署外掛:

mvn clean deploy -P sonatype-oss-release -Darguments="gpg.passphrase=金鑰密碼"

如果使用eclipse的mvn外掛釋出的話,配置如下: 

 

如果釋出成功,就可以到stagingRepositories(https://oss.sonatype.org/#stagingRepositories)中查看了。

釋出到中央倉庫

進入stagingRepositories檢視釋出好的構件,點選左側的Staging Repositories,一般最後一個就是剛剛釋出的依賴,此時的構件狀態為open。 

選中剛才釋出的構件,並點選上方的Close–>Confirm,在下邊的Activity選項卡中檢視狀態,當狀態變成closed後,執行Release–>Confirm,並在下邊的Activity選項卡中檢視狀態,成功後構件自動刪除,一小段時間(約10分鐘)後即可同步到maven的中央倉庫,再過1-2個小時就可以搜尋到該依賴了(https://search.maven.org)。

其它問題

配置pom.xml時,為什麼沒有配置倉庫的地址?

為什麼我只是在settings.xml中配置了id,又沒有配置這個id對應的伺服器地址,Maven是如果找到我想上傳的伺服器地址?

還記的之前我們在pom.xml中配置的<parent>節點麼?這個節點中有如下內容:

    <distributionManagement>

        <snapshotRepository>

            <id>sonatype-nexus-snapshots</id>

            <name>Sonatype Nexus Snapshots</name>

            <url>${sonatypeOssDistMgmtSnapshotsUrl}</url>

        </snapshotRepository>

        <repository>

            <id>sonatype-nexus-staging</id>

            <name>Nexus Release Repository</name>

            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>

        </repository>

    </distributionManagement>

我們的專案相當於繼承了這個配置,所以Maven根據我們在settings.xml中配置的id找到pom.xml中配置的url來上傳依賴。

其實我們完全可以不配置<parent>節點,而是根據實際需要自己配置對應的內容,只不過麻煩些,對新手不太友好。

如何配置生成javadoc和sources?

只要按照之前的章節配置了<parent>節點,就不需要單獨配置,因為已經繼承瞭如下內容:

 

如果不符合想要的效果,可以在pom.xml中覆蓋修改。

Snapshot/Staging/Release倉庫的地址分別是什麼?

其中sonatype-nexus-snapshots和sonatype-nexus-staging倉庫的地址可以在<parent>節點中檢視:

sonatype-nexus-snapshots:

https://oss.sonatype.org/content/repositories/snapshots/

sonatype-nexus-staging:

https://oss.sonatype.org/service/local/staging/deploy/maven2/

sonatype-nexus-release:

https://repo1.maven.org/maven2

Maven怎麼知道把我的依賴上傳到哪個倉庫?

maven會根據模組的版本號中是否帶有-SNAPSHOT來判斷是快照版本還是正式版本。如果是快照版本,那麼在mvn deploy時會自動釋出到快照版本庫中,而使用快照版本的模組,在不更改版本號的情況下,直接編譯打包時,maven會自動從映象伺服器上下載最新的快照版本。如果是正式釋出版本,那麼在mvn deploy時會自動釋出到正式版本庫中,而使用正式版本的模組,在不更改版本號的情況下,編譯打包時如果本地已經存在該版本的模組則不會主動去映象伺服器上下載。

所以,我們在開發階段,可以將公用庫的版本設定為快照版本,而被依賴元件則引用快照版本進行開發,在公用庫的快照版本更新後,我們也不需要修改pom檔案提示版本號來下載新的版本,直接mvn執行相關編譯、打包命令即可重新下載最新的快照庫了,從而也方便了我們進行開發。

每次釋出,如果要切換髮布倉庫都要修改版本號,有沒有辦法簡化?

在pom.xml中做如下配置:

 

<groupId>com.github.jiangxincode</groupId>

<artifactId>simian-maven-plugin</artifactId>

<version>${project.release.version}</version>

<packaging>maven-plugin</packaging>

<name>Simian Maven Plugin</name>

<url>https://github.com/jiangxincode/simian-maven-plugin</url>

<properties>

<project.release.version>0.0.5-SNAPSHOT</project.release.version>

</properties>

<profiles>

<profile>

<id>release</id>

<properties>

<project.release.version>0.0.5</project.release.version>

</properties>

</profile>

</profiles>

 

首先我們看到pom檔案中version的定義是採用佔位符的形式,這樣的好處是可以根據不同的profile來替換版本資訊。

如果在釋出時使用mvn deploy -P release 的命令,那麼會自動使用0.0.5作為釋出版本,那麼根據maven處理snapshot和release的規則,由於版本號後不帶-SNAPSHOT故當成是正式釋出版本,會被髮布到release倉庫;

 

如果釋出時使用mvn deploy命令,那麼就會使用預設的版本號0.0.5-SNAPSHOT,此時maven會認為是快照版本,會自動釋出到快照版本庫。

 

部署到snapshot倉庫時,jar包會帶上時間戳,怎麼辦?

 

這沒關係,maven會自動取相應版本最新的jar包;

 

提交到release倉庫是,報錯怎麼辦?

報錯資訊如下:

 

Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy (default-deploy) on project simian-maven-plugin: Failed to deploy artifacts: Could not transfer artifact...from/to release...

 

這是因為elease的部署策略是【disable redeploy】,不允許覆蓋更新元件。修改一下版本號,再提交即可。

 

參考內容

Github開源Java專案(IJPay)上傳到Maven Central 詳細介紹:https://blog.csdn.net/zyw_java/article/details/77802615

 

歡迎和大家交流技術相關問題:

郵箱: [email protected]

部落格園地址: <http://www.cnblogs.com/jiangxinnju>

GitHub地址: <https://github.com/jiangxincode>

知乎地址: <https://www.zhihu.com/people/jiangxinnju>