1. 程式人生 > >一起學Maven(Maven倉庫管理器之應用Nexus)

一起學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檔案中,定義了中央倉庫的位置,配置檔案如下所示

 ………………………………………………………………
 <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>
 ………………………………………………………………
    其中url指向了中央倉庫的位置http://repo.maven.apache.org/maven2,

    而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倉庫中。同時,根據大公司的要求,建立了專有的倉庫,並且學習瞭如何進行使用者管理,角色許可權管理等等。

    如有什麼疑問或者建議意見都可以提出,本人在此不勝感激,同時,同樣恭祝大家學習愉快!