一起學Maven(Maven倉庫管理器之應用Nexus)
注:本博文是接著上一章節繼續講解
Nexus-私有倉庫的配置
點選左邊導航欄的Repositories選項,會顯示一個所有倉庫及倉庫組的列表,Type欄位的值有group,hosted,proxy,virtual(在Maven1中使用,這裡不需要關心),如圖14所示:
圖14
在這裡:
- hosted,本地倉庫,這個倉庫主要是用來存放本地的依賴包,服務於區域網,不訪問公網
- proxy,代理倉庫,用來存放nexus從公網中獲取的依賴包,這裡有中央倉庫,Apache和Codehaus開源網站的依賴包
- group,倉庫組,用來合併多個hosted/proxy倉庫,通常我們配置maven依賴倉庫組
比如點選Type為group,如圖15所示:
圖15
會發現,在Ordered Group Repositories中,有所有hosted和proxy的倉庫,而圖15中箭頭所指的地方有四種類型的倉庫,分別是Releases(hosted), Snapshots(hosted),
3rd Party(hosted),Central(proxy),而Central指的是中央倉庫,不知道大家是否還有印象,在本系列第二章節,曾經提到中央倉庫的位置,存在於apache-maven-3.1.1\lib\maven-model-builder-3.1.1.jar中的org\apache\maven\model\pom-4.0.0.xml檔案中,定義了中央倉庫的位置,配置檔案如下所示
其中url指向了中央倉庫的位置http://repo.maven.apache.org/maven2,……………………………………………………………… <repositories> <repository> <id>central</id> <name>Central Repository</name> <url>http://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> ………………………………………………………………
而Releases, Snapshots, 3rd Party,主要功能如下:
Releases: 這裡存放我們自己專案中釋出的構建, 通常是Release版本
Snapshots: 這個倉庫非常的有用, 它的目的是讓我們可以釋出那些非release版本, 非穩定版本, 比如我們在trunk下開發一個專案,在正式release之前你可能需要臨時釋出一個版本給你的同伴使用, 因為你的同伴正在依賴你的模組開發, 那麼這個時候我們就可以釋出Snapshot版本到這個倉庫, 你的同伴就可以通過簡單的命令來獲取和使用這個臨時版本
3rd Party: 顧名思義, 第三方庫, 你可能會問不是有中央倉庫來管理第三方庫嘛, 沒錯, 這裡的是指可以讓你新增自己的第三方庫, 比如有些構件在中央倉庫是不存在的. 比如你在中央倉庫找不到Oracle 的JDBC驅動, 這個時候我們就需要自己新增到3rd party倉庫
在settings.xml中配置遠端倉庫
既然這個group已經包含了四個倉庫,那麼只要將這個組進行配置,在Maven中就會引用所有在這個組對應的倉庫中的依賴包,配置的URL地址為http://localhost:8081/nexus/content/groups/public/。我們可以配置在專案中的user-parent的pom.xml檔案中,但此時會有個問題,這樣的配置僅僅是對當前的專案有效(user-parent是父檔案,其子檔案繼承),如果專案有很多,而不需要每個專案都要進行以上設定,也就是隻要設定一次,然後本機的專案就會自動從nexus中尋找依賴包,如何做呢?
Maven倉庫組
因為Maven在本機中是同一個,所以只要在Maven所對應的settings.xml中進行配置就好,(本部落格settings.xml對應的路徑為E:\Workspaces\Maven\settings.xml),配置如下:
…………………………………………
<profiles>
<profile>
<id>nexusProFile</id>
<repositories>
<repository>
<id>localNexus</id>
<name>Nexus Repository</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<!-- 此選項預設是關閉的,手動開啟 -->
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<!-- 啟用上面的配置 -->
<activeProfile>nexusProFile</activeProfile>
</activeProfiles>
…………………………………………
Maven中的profile是一組可選的配置,可以用來設定或者覆蓋配置預設值。有了profile,你就可以為不同的環境定製構建。 這個時候,做個試驗,可以在user-core的pom.xml中加入以下依賴(這個依賴包並不存在於本地或者Nexus倉庫中)
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
</dependency>
新增好後進行儲存,會發現Eclipse的控制檯中有如圖16的資訊:圖16
這表明,Maven已經從通過Nexus下載依賴包了,而Nexus從中央工廠中進行下載。
接著看圖17:
圖17
這也驗證了Nexus已經將mybatis的依賴包下載到了倉庫中。
但此時會有個問題,如果將Nexus服務停止,如圖18所示
圖18
這個時候在user-core的pom.xml中新增原來沒有的依賴配置檔案(可以隨便找個不存在的jar依賴檔案進行測試,這裡用使用Spring)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
這個時候在Eclipse中點選儲存,會發現如下的資訊14-3-7 GMT+0800下午8:29:41: [INFO] Using org.eclipse.m2e.jdt.JarLifecycleMapping lifecycle mapping for MavenProject: com.steven.user:user-core:0.0.1-SNAPSHOT @ E:\Workspaces\STSWorkspace\user-core\pom.xml.
14-3-7 GMT+0800下午8:29:42: [INFO] Number of application's worked threads is 4
14-3-7 GMT+0800下午8:29:44: [INFO] Downloaded http://localhost:8081/nexus/content/groups/public/org/springframework/spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.pom
14-3-7 GMT+0800下午8:29:44: [INFO] Number of application's worked threads is 4
14-3-7 GMT+0800下午8:29:47: [INFO] Downloading http://repo.maven.apache.org/maven2/org/springframework/spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.pom
14-3-7 GMT+0800下午8:29:47: [INFO] Downloaded http://repo.maven.apache.org/maven2/org/springframework/spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.pom
………………………………………………………………………………
首先通過Nexus下載,但服務已經關閉,這個時候仍然可以下載,而且通過中央倉庫進行下載。但在專案中,不允許本地倉庫直接下載中央倉庫的依賴包,這個時候就需要進行對中央倉庫進行覆蓋,使之只能通過Nexus訪問中央倉庫,這個時候需要對映象進行配置。
在settings.xml中配置映象
首先配置映象,使得只有通過Nexus才可以訪問中央倉庫
…………………………………………………………
<mirror>
<id>nexusMirror</id>
<mirrorOf>*</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://localhost:8081/nexus/content/groups/public/</url>
</mirror>
…………………………………………………………
這裡的*號代表所有的倉庫都是通過這個url地址訪問,這個時候可以附加一段配置,原來的中央倉庫中snapshots版本的依賴包預設是不可以下載的,但可以通過以下配置進行修改
……………………………………
</profiles>
……………………………………
<profile>
<id>centralProFile</id>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<!--由於配置過映象,這個url不起作用-->
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<!--覆蓋中央倉庫中的false配置,可以從中央倉庫中下載snapshot版本-->
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<!-- 啟用上面的配置 -->
<activeProfile>centralProFile</activeProfile>
</activeProfiles>
……………………………………
這樣進行儲存後,既可生效。注意:配置檔案settings.xml中會預設有相應的mirror和profile的例子,但都是註釋掉的,我們在進行以上的改動時候,可以進行對其複製粘貼後進行修改,這樣不容易出錯。
驗證:(此時沒有開啟nexus服務)
隨便找個不存在的jar依賴檔案進行測試,
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
跟剛才的步驟一樣,但此時儲存後,Eclipse控制檯中的資訊如下所示:14-3-7 GMT+0800下午9:13:58: [INFO] Downloaded http://localhost:8081/nexus/content/groups/public/org/mortbay/jetty/jetty/6.1.25/jetty-6.1.25.pom
14-3-7 GMT+0800下午9:13:58: [INFO] Using org.eclipse.m2e.jdt.JarLifecycleMapping lifecycle mapping for MavenProject: com.steven.user:user-service:0.0.1-SNAPSHOT @ E:\Workspaces\STSWorkspace\user-service\pom.xml.
14-3-7 GMT+0800下午9:13:58: [INFO] Number of application's worked threads is 4
14-3-7 GMT+0800下午9:14:02: [INFO] Using 'UTF-8' encoding to copy filtered resources.
14-3-7 GMT+0800下午9:14:02: [INFO] skip non existing resourceDirectory E:\Workspaces\STSWorkspace\user-service\src\main\resources
14-3-7 GMT+0800下午9:14:02: [INFO] Using 'UTF-8' encoding to copy filtered resources.
14-3-7 GMT+0800下午9:14:02: [INFO] skip non existing resourceDirectory E:\Workspaces\STSWorkspace\user-service\src\test\resources
這裡只能通過Nexus下載依賴包,但是由於服務停止,所以下載失敗,而如果此時將服務開啟
圖19
然後在Eclipse中重新整理依賴包所在的pom.xml檔案,
如果沒有任何問題,則在控制檯中顯示如下資訊:
14-3-8 GMT+0800上午12:00:31: [INFO] Downloading http://localhost:8081/nexus/content/groups/public/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar
14-3-8 GMT+0800上午12:00:31: [INFO] Downloaded http://localhost:8081/nexus/content/groups/public/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar
但此時可能出現以下問題[ERROR] Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:2.5
原因:這是因為在進行配置後,所有本地倉庫的依賴包都將通過nexus私有倉庫訪問中央倉庫進行下載,而此時在載入一些Maven外掛的時候,由於一開始本地倉庫中已經存在,而私有倉庫中沒有這些依賴包的索引(就是指在nexus中存在對依賴包的GAV標識),這個時候就會容易報錯。解決思路:
思路1:
一開始可以進行對索引更新,具體參照圖20所示
圖20
這樣設定以後, Nexus會自動從遠端中央倉庫下載索引檔案,索引檔案很大,需要很久等待時間。
思路2:
錯誤資訊也有如下所示的提示:
Could not calculate build plan: Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom:2.7.1 from http://repo1.maven.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.apache.maven.plugins:maven-surefire-plugin:pom:2.7.1 from/to central (http://repo1.maven.org/maven2): Access denied to http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/2.7.1/maven-surefire-plugin-2.7.1.pom.
解決方案:1.找到maven庫目錄,進入:\repository\org\apache\maven\plugins\maven-surefire-plugin\2.7.1
2.若2.7.1目錄下只有,"maven-surefire-plugin-2.7.1.pom.lastUpdated" 則需要到http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/2.7.1/,把裡面的檔案下載下來放到2.7.1資料夾中
3.刪除2.7.1下的maven-surefire-plugin-2.7.1.pom.lastUpdated檔案。
4.專案右鍵-->maven-->Update Project即可。
思路3:
首先關掉Eclipse,停止Nexus執行,然後將本地E:\Workspaces\Maven\repository中所有的依賴包刪除,然後啟動Nexus,開啟Eclipse,這時候將通過Nexus進行下載依賴包到本地倉庫中,一般情況可以解決問題,如果還有思路2中的錯誤資訊,則執行思路2。
通過Maven部署專案到Nexus中
當專案已經編寫完成,需要部署到Nexus中,這樣團隊人員可以通過Nexus下載到自己的本地倉庫中,比如說,我是編寫user-core的模組的,部署到Nexus中,需要以下兩個步驟,
1、需要配置user-core的pom.xml檔案,定義釋出的版本以及釋出到Nexus本地庫的哪個倉庫中,具體如下所示:
………………………………………………………………
<distributionManagement>
<repository>
<id>user-core-release</id>
<name>user core release</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>user-core-snapshot</id>
<name>user core snapshot</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
………………………………………………………………
2、配置本地settings.xml檔案,讓部署過程中有足夠的許可權,而Nexus中本來存在的有三個使用者,如圖21所示:
圖21
而部署使用deployment使用者,具體的配置如下
………………………………………………………………
<server>
<id>user-core-release</id>
<username>deployment</username>
<password>deployment123</password>
</server>
<server>
<id>user-core-snapshot</id>
<username>deployment</username>
<password>deployment123</password>
</server>
………………………………………………………………
完成以上兩個步驟,此時進行部署(deploy)操作,如圖22所示:
圖22
這個時候部署成功,然後我們可以在Nexus中看到部署後的結果,如圖23所示
圖23
在Snapshots的索引中可以檢視到剛剛部署的user-core模組。
通過Nexus搜尋構件
首先我們來明確一下構件的含義,
構件:構件是系統中實際存在的可更換部分,它實現特定的功能,符合一套介面標準並實現一組介面,而在我們這裡就是我們要使用的即將需找的依賴。
但在我們實際使用構件的過程中通常遇到一個問題,有時候我緊緊知道我所需要的構建的大致名字,並不知道全稱或group id, 這是件非常頭疼的事情. Nexus基於Nexus indexer(索引)的搜尋功能幫我們解決了這個問題。
還記得剛才我們在解決Could not calculate build plan...問題的時候,給出的思路1,其思想就是,通過更改Download Remote Indexes的狀態為True,使得Nexus從中央倉庫中將所有構件的資訊同步到本地,這樣在以後的開發中,就可以直接下載私有倉庫中的依賴,就不需要Nexus還要去中央倉庫中下載了。下面就來領略Nexus搜尋構件的方便之處。
如圖所示:
圖24
這裡有以下幾種搜尋方式:
keyword(關鍵字查詢), classname(類名查詢), GAV(groupId,artifactId,version組合查詢), checksum(校驗和查詢),這裡我認為前三種使用的最多。
比如,剛剛通過部署後的user-core模組,這個模組正好被其他專案人員使用到,他知道模組的名稱叫user-core,這個時候,可以通過GAV的方式進行查詢,如圖所示:
圖25
查出來之後,只要將依賴檔案複製到專案的pom.xml配置中,就可以從私有倉庫中下載到其本地倉庫進行使用了。
建立本地倉庫並設定許可權
建立倉庫
在大公司的專案開發中,不可能所有的Snapshots和Releases版本都發布到Nexus中預設對應的Snapshots和Releases倉庫中,我們可以給每個專案建立自己的本地倉庫,並賦予相應的角色許可權進行操作。比如建立一個UserRelease倉庫用來儲存User專案的Release版本,這個時候,操作如圖所示:
圖26
接著將資訊填入New Hosted Repository中,如圖27所示
圖27
這個時候就建立了UserRelease的本地倉庫,如圖所示
圖28
建立許可權
雖然我們已經建立了UserRelease倉庫,但倉庫的許可權僅為預覽,如果讓其可以有增刪改查的許可權,只要點選圖中Add,如圖所示:
圖29
接著進行資訊填入,如圖30所示
圖30
這個時候UserRelease倉庫就擁有了所有的許可權,如圖31所示
圖31
建立角色
雖然有了許可權,但在使用的過程中,進一步建立一個角色,對角色新增相應的許可權,然後在讓角色中新增相應的使用者,這樣在釋出的時候就可以達到許可權的最細緻化,管理起來更加方面。
如圖32,建立角色
圖32
然後進行填寫資訊,如圖33
圖33
在這裡有Add按鈕,點選按鈕的時候進行如下操作
圖34
此時,建立角色後如圖35所示:
圖35
建立使用者
角色建立好後就可以建立使用者,通過專有的使用者來進行專有專案的部署和其他操作,如圖建立使用者
圖36
然後填入資訊,如圖所示
圖37
在圖37中點選Add按鈕出現圖38所示的選項,如下操作
圖38
就是選擇該使用者所屬的角色,而角色擁有所有的許可權,完成後如圖39所示
圖39
注:在以上操作中,我們首先建立一個本地倉庫(這裡是Release版本的,專案中可以在建立一個Snapshot版本,操作過程同上),然後給這個倉庫賦予許可權,然後將這些許可權通過一個角色進行擁有,當然在這裡可以建立不同的角色賦予不同的許可權,這時候,建立一個使用者,使得該使用者擔當一個角色,這樣的話,這個使用者就可以擁有這個角色中的許可權,下面就可以按需對所在的專案使用相應的使用者進行操作了。
這樣根據以上情況可以建立UserSnapshot的倉庫,以及將所有的許可權付給不同的角色,或者可以讓UserReleaseRole同樣擁有UserSnapshot的所有許可權,並且同樣的使用者擁有Release和Snapshot倉庫的所有許可權,這樣的話如果進行部署,就可以如下進行配置,在對應部署模組的pom.xml中可以這樣配置
………………………………………………………………
<distributionManagement>
<repository>
<id>user-core-release</id>
<name>user core release</name>
<url>http://localhost:8081/nexus/content/repositories/UserRelease/</url>
</repository>
<snapshotRepository>
<id>user-core-snapshot</id>
<name>user core snapshot</name>
<url>http://localhost:8081/nexus/content/repositories/UserSnapshots/</url>
</snapshotRepository>
</distributionManagement>
………………………………………………………………
而在settings.xml中就可以這樣進行配置
………………………………………………………………
<server>
<id>user-core-release</id>
<username>UserRelease</username>
<password>user123</password>
</server>
<server>
<id>user-core-snapshot</id>
<username>UserRelease</username>
<password>user123</password>
</server>
………………………………………………………………
這樣就可以把相應的Release和Snapshot版本部署到相應的Nexus倉庫中了。
總結
本章節通過對倉庫管理器Nexus的講解,包括如何下載安裝Nexus,配置Nexus代理中央倉庫,管理Nexus的代理倉庫,本地倉庫,以及倉庫組。並幫助你瞭解如何通過Nexus搜尋構件。最後,如何在Maven中配置Nexus倉庫,以及如何部署構件到Nexus倉庫中。同時,根據大公司的要求,建立了專有的倉庫,並且學習瞭如何進行使用者管理,角色許可權管理等等。
如有什麼疑問或者建議意見都可以提出,本人在此不勝感激,同時,同樣恭祝大家學習愉快!