我分兩部分來介紹,首先介紹一下Maven的倉庫,然後在說一下如何通過Nexus來建立我們自己的倉庫,以及如何使用。
Maven 倉庫
在以前使用Ant的時候,我們會建立一個lib目錄在存放我們的jar包,比如項目所依賴的第三方包,每建立一個項目都要建立一個lib,不停的做copy工作,不僅是對于磁盤的浪費,而且也造成了版本管理上的麻煩。而且我們還需要通過送出到svn上來對lib進行管理,但是svn對于這種二進制檔案的管理并不出色。
Maven倉庫的初衷就是為了解決這個問題。 maven倉庫是所有常用的第三方依賴包的集中營。這樣所有的Maven項目就可以從這個倉庫中擷取所需要的資源,Maven倉庫中對jar通過Group Id, Atifact Id, version 來管理,是以Maven項目可以很友善的進行依賴管理。你不需要自己來管理這個龐大的資源倉庫,當然你可以建立一個公司層面的倉庫,這個我在這個章節的後面會介紹。
Maven 倉庫的兩個概念:本地倉庫和遠端倉庫
本地倉庫是遠端倉庫的一個緩沖和子集,當你建構Maven項目的時候,首先會從本地倉庫查找資源,如果沒有,那麼Maven會從遠端倉庫下載下傳到你本地倉庫。這樣在你下次使用的時候就不需要從遠端下載下傳了。如果你所需要的jar包版本在本地倉庫沒有,而且也不存在于遠端倉庫,Maven在建構的時候會報錯,這種情況可能發生在有些jar包的新版本沒有在Maven倉庫中及時更新。
Maven預設的本地倉庫位址為${user.home}/.m2/repository 。也就是說,一個使用者會對應的擁有一個本地倉庫。當然你可以通過修改${user.home}/.m2/settings.xml 配置這個位址:
?
1 2 3 4 5 | |
如果你想讓所有的使用者使用統一的配置,那麼你可以修改${M2_HOME}/conf/setting.xml
還可以通過在運作時指定目錄(不推薦這麼做):
?
1 | |
當我們建立一個簡單的Maven項目後(隻需要在pom.xml配置好依賴項),運作mvn clean install就可以把項目建構好,maven會自動從中央倉庫下載下傳所需的依賴項(即jar包)。這個中央倉庫定義在${M2_HOME}/lib/maven-2.0.10-uber.jar 裡面。你可以在裡面找到/org/apache/maven/project/pom-4.0.0.xml這個檔案,在這個檔案裡面定義了中央倉庫的位址:
?
1 2 3 4 5 6 7 8 9 10 11 | |
在 POM 中配置遠端倉庫
當某個依賴項存在于第三方的公共倉庫時,我們需要配置其他遠端倉庫呢。下面是在pom.xml裡面配置一個遠端倉庫的例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
這裡我們可以看到,允許配置多個repository和 plugin repository,其中<releases><enabled>true</enabled></releases>告訴Maven可以從這個倉庫下載下傳releases版本的構件,而<snapshots><enabled>false</enabled></snapshots>告訴Maven不要從這個倉庫下載下傳snapshot版本的構件。
Maven在使用第三方構件和插件時是分開來配置的,是以如果我們也希望插件的下載下傳也通過我們的本地倉庫來下載下傳,那麼我們就需要配置pluginRepository.
之是以不允許從某些倉庫下載下傳snapshot版本,是因為snapshot版本不穩定,但是某些snapshot版本,比如公司内部正在開發的項目, 是必須的
至于<pluginRepositories>,這是配置Maven從什麼地方下載下傳插件構件,Maven的所有行為都是通過插件來完成的。 <pluginRepository>的配置與<repository>類似,這裡就不多說了。
在 settings.xml 中配置遠端倉庫
pom.xml的作用範圍限于一個項目, 但一個公司/組織通常不隻開發一個項目,那麼為了避免重複配置,那麼我們可以把一些公共配置放在${MAVEN_HOME}/conf/setting.xml(或${user.home}/.m2/setting.xml中。下面是在setting.xml中配置一個遠端倉庫的例子.
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
這裡通過<activeProfile>元素來激活這個profile,這樣我們就可以全局的使用這個配置,不再需要為每個POM做重複的配置了(也可以針對特定的條件激活,比如某些profile隻有在使用JDK 1.4時才生效)。
在實際的操作過程中,setting.xml最好不要配置遠端倉庫,最好能夠通過nexus建立公司或者組織自己的倉庫,然後把位址指向自己的倉庫,後面我會介紹為什麼要這麼做以及怎麼做。
配置maven倉庫鏡像
當你連接配接中央倉庫時速度很慢,或有些國外的第三方倉庫無法被通路時,你可以在setting.xml中為這些倉庫指定一個鏡像來加快下載下傳依賴項的速度。下面是一個配置鏡像的例子
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
這裡的 <mirrorOf>必須指定某個<repository>的Id. 如果想為所有的倉庫做鏡像, 那麼可以改為:<mirrorOf>*</mirrorOf>
利用 Nexus 來建構企業級 Maven 倉庫
Nexus簡介
Nexus是一個Maven倉庫管理器,用來搭建私有倉庫伺服器。建立公司/組織的私有倉庫的的好處是便于管理,節省公網帶寬,利用内網下載下傳依賴項速度快,還有一個非常有用的功能就是能有效管理内部項目的SNAPSHOT版本,實作各個子產品間的共享.
安裝 Nexus
可以從http://nexus.sonatype.org/downloads/ 擷取最新版本的nexus,本文以1.3.4為例進行說明。
Nexus提供了兩種安裝方式,内嵌Jetty的捆綁包(bundle)和WAR包。前者解壓後即可單獨運作,隻要系統中安裝了JRE, 後者需要一個Servlet容器來運作.
使用捆綁包安裝
如果你使用Windows,那麼下載下傳nexus-webapp-1.3. 4-bundle.zip,并将其解壓至任意目錄,如D:/tools,然後轉到D:\tools\nexus-webapp-1.3.4\bin\jsw\indows-x86-32 ,輕按兩下運作Nexus.bat。 如果你是在linux下安裝,那麼就下載下傳nexus-webapp-1.3. 4 -bundle.tar.gz,解壓後運作nexus.sh。nexus還支援solaris,macos等作業系統。
當你在控制台看到“Started [email protected]:8081”之後,說明Nexus啟動成功了。 打開浏覽器,通路http://127.0.0.1:8081/nexus,使用管理者的帳号(admin)和密碼(admin123)登入, 會看到如下的頁面:

在這裡可以進行管理倉庫,配置Nexus系統,管理任務,管理使用者,角色,權限,檢視系統的RSS源,管理及檢視系統日志等操作。
使用War包安裝
下載下傳WAR包,然後将其釋出到servlet容器中即可
到此我們已經安裝好Nexus,下面介紹一下Nexus常用的功能和使用方法。
配置中央倉庫
在左邊菜單欄裡選擇Repositories, 會看到如下的界面:
其中右邊欄上半部分列出目前nexus管理的repository,黑體字是類型為group的repository. 這裡簡單介紹下幾種repository的類型:
- hosted,本地倉庫。通常我們會部署自己的構件到這一類型的倉庫。比如公司/組織開發的項目
- proxy,代理倉庫,它們被用來代理遠端的公共倉庫,如maven中央倉庫或一些第三方公共倉庫。
- group,倉庫組,用來合并多個hosted/proxy倉庫,當你的項目希望在多個repository使用依賴項時,無需引用多個倉庫了,隻需要引用一個類型為group的repository即可。
Maven central是Maven的中央倉庫,點選它并選擇configuration标簽欄,我們會看到下面的頁面:
這裡有幾個配置項是經常用到的:
- Override local storage location: 該選項允許配置 Nexus本地倉庫的存放位址,用來覆寫其預設的存放位址
- Remote storage location: 該選項允許配置遠端倉庫的位址。一般為了提高代理速度,你可以将其修改為國内的鏡像位址。預設值是http://repo1.maven.org/maven2/
- Download remote indexes: 該選項配置是否下載下傳遠端索引檔案。 建議配置為true,這樣我們便可以通過nexus的搜尋功能來搜尋我們需要的依賴項。
添加代理倉庫(proxy)
nexus預設提供了Maven central這個代理倉庫,如果你需要添加其他代理倉庫,那麼可以點選左邊欄頁面上的Repositories連結,然後在右邊欄頁面上依次點選add -> add proxy repository, 随後出現以下頁面:
根據提示填寫相關資訊儲存即可。
管理本地倉庫(hosted)
Nexus預定義了三種本地倉庫,分别是Releases, Snapshots, 3rd Party. 下面分别介紹一下這三種類型倉庫的作用
- Releases: 存放穩定版本的構件。比如我們完成了一個版本的下數元件的開發,就可以把它釋出到這裡。
- Snapshots: 存放快照版本的構件。 比如一個下數元件在完成所有開發和測試工作之前,是不應該釋出到release倉庫的,但可能其他項目隻需用到這個元件的某些接口,隻要這些接口完成了開發并通過測試,就可以拿來使用, 進而實作多個項目并行開發。
-
3rd Party: 存放其他第三方構件。你可能會問, 不是有中央倉庫和其他第三方公共倉庫來管理這些依賴項了嗎?沒錯。但由于某些開源項目出現的時間比maven要早,是以他們大都沒有采用maven方式進行建構。 其他還包括包括一些非開源或使用maven 1.x建構的元件. 我們可以把這類元件通通添加到這裡。
建立本地倉庫的方法很簡單。點選Repository面闆上方的Add按鈕,然後選擇Hosted Repository,然後在下方的配置面闆中輸入相關資訊。 注意根據自己的需要選擇本地倉庫的類型
倉庫組(group)
通過前面介紹我們了解到, 可以建立多個代理倉庫和本地倉庫. 但如果沒有倉庫組的概念,那麼當需要引用這些倉庫時, 就需要将他們逐個添加到pom.xml或setting.xml. 倉庫組是為了簡化倉庫的引用而提出的。有了倉庫組的概念, 我們可以把倉庫根據不同目的進行分組,比如把常用的歸到一組或根據通路權限分組, 然後直接聲明引用某個倉庫組即可. 下面是pom.xml中聲明引用一個nexus倉庫組的例子:
?
1 2 3 4 5 6 7 8 9 10 11 | |
可以看到聲明引用一個倉庫組和一個普通的遠端倉庫,配置的寫法完全一樣。
maven本身沒有倉庫組的概念
Nexus中預設了2個倉庫組, 分别是public repositories和public snapshot repositories. 如圖:
public repository預設包含本地倉庫的Releases, snapshots和3rd party以及代理倉庫的Maven Central. 你可以在Configuration配置頁添加其他倉庫到這個倉庫組。 如果需要,你還可以建立一個倉庫組,方法是點選 Add->Repository Group, 當New Repository Group界面後,填入ID, name 等相關資訊, 然後在右邊Available Repositories 欄裡可以選擇你要添加的倉庫到你建立的倉庫組.
通過 Nexus 搜尋構件
在開發過程中過程中,我們往往隻記得某個構件的大緻名字,這時我們可以通過nexus提供的構件搜尋功能查詢該構件的完整配置資訊(groupId,artifactId,version).如果通過nexus搜不到某個的構件,那說明這個構件不在目前nexus所登記的倉庫中,可能需要添加額外的代理倉庫或手工上傳某個構件。
在使用nexus的搜尋功能之前,必須先讓nexus所登記的倉庫建立索引檔案, Nexus預設是不為每個倉庫建立索引檔案的,因為建立像中央倉庫這樣的索引檔案需要耗費比較大的網絡帶寬和事件,僅索引檔案就要幾十兆. 要開啟中央倉庫的索引檔案下載下傳功能需要在Maven Central的配置頁中, 把Download Remote Indexes改為true. 如圖:
這樣設定之後, Nexus會自動從遠端中央倉庫下載下傳索引檔案, 為了檢驗索引檔案自動下載下傳是否生效,可以切換到Browse标簽頁,如圖:
如果出現類似于以上檔案夾,那說明索引檔案已經建立成功.
下面我們試一下搜尋功能, 搜尋欄輸入testing, 查詢結果如下:
這是模糊查詢的結果,當然如果你知道更多資訊,比如版本号等,你可以使用進階搜尋,點選進階搜尋後,右邊界面會提供集中搜尋方式:keyword, classname, GAV, checksum
比如我們這裡選擇GAV模式. 假設我隻知道artifact的名字(如testng)和版本号(如5.8), 其他的我不知道, 那麼就在artifact 和 version處分别輸入testng 和 5.8 , 搜尋結果如下:
如果你不知道知道構件的名稱, 隻知道classname, 那麼你也可以通過class name 的方式搜尋,這裡就不再贅述。
當你選中某項搜尋結果, 頁面的下方會出現這個構件的詳細資訊, 并且會列出這個構件的Maven依賴配置, 你可以直接拷貝到你的pom檔案中使用,這是個非常實用的功能:
在 Maven 中使用Nexus
到此我們介紹了如何安裝和使用Nexus以及其基本配置, 那麼如何在Maven來使用Nexus本地倉庫呢?其實和配置遠端倉庫的方法一樣。下面是在settings.xml中添加了一個nexus本地倉庫的例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
你也可以在pom.xml中聲明引用某個nexus倉庫。
構件部署
有些時候我們需要部署構件到Nexus的3rd party, 比如我們在中央倉庫找不到我們需要的構件, 我們可以通過Nexus的UI界面來上傳構件:
點選左邊菜單欄的 Repositories, 然後點選右邊界面的3rd party, 選擇界面下方的Artifact Upload, 這個時候出現以下界面:
上傳構件需要兩個步驟,一個是定義檔案的上傳,再就是構件的實體檔案.第一部分定義檔案可以是POM檔案, 這也是比較推薦的方式, 如果沒有pom檔案,可以選擇以參數的形式輸入。第二部分是上傳構件的實體檔案。這裡簡單說一下Classifier和Extension, 這兩個都是選填項. Classifier用來差別同功能的構件用于不同的場景, 比如這個構件是分别針對JDK14和JDK15做了2個功能一樣的Jar, 這個時候你就需要指定這個構件的Classifier為JDK14還是JDK15. Extension是指擴充名,如果不提供,那麼會自動取這個構件的Packaging Type作為擴充名, 比如ear, jar, war 等等. (Packaging Type是在第一步中通過pom檔案或者手工輸入得到的)
剛才說了3rd party的部署, 對于releases 和 snapshots的部署也是一樣的操作過程.
一般我們會通過UI 界面來部署一些缺失的構件。對于自己開發的構件還有另一種簡單的部署方式, 即通過指令mvn deploy進行部署。但使用這種部署方式需要在pom.xml中添加一些配置,比如:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
這裡告訴Maven當我要釋出release版本或者snapshot版本時,把建構好的成品上傳到哪個伺服器位址。
最後還要在setting.xml裡面配置一個有部署權限的Nexus的帳号和密碼
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
至此 我們就可以通過指令mvn deploy來釋出我們項目到本地倉庫了.
這裡我們使用了admin來進行部署,一般建議使用一個具有部署權限的賬号執行部署操作。
補充
1、 發現配置了nexus倉庫組之後,下載下傳構件抛異常
0-10-3 下午05時09分43秒: Build error for /com.newyulong.iptv.domain.entity/pom.xml; org.apache.maven.plugin.PluginResolutionException: Plugin org.apache.maven.plugins:maven-resources-plugin:2.4.1 or one of its dependencies could not be resolved: Missing:
----------
1) org.apache.maven.plugins:maven-resources-plugin:maven-plugin:2.4.1
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=org.apache.maven.plugins -DartifactId=maven-resources-plugin -Dversion=2.4.1 -Dpackaging=maven-plugin -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=org.apache.maven.plugins -DartifactId=maven-resources-plugin -Dversion=2.4.1 -Dpackaging=maven-plugin -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
----------
1 required artifact is missing.
for artifact:
org.apache.maven.plugins:maven-resources-plugin:maven-plugin:2.4.1
from the specified remote repositories:
Nexus (http://localhost:8181/nexus/content/groups/public , releases=true, snapshots=false)
這裡的主要原因是配置nexus裡面的Public Repositories 順序和條件出錯,導緻不能下載下傳構件。比如這個public repositories:
這個是正确的配置順序。其中左邊的是正在使用的定義好的倉庫,右邊的是候選的倉庫。在這個例子中,nexus下載下傳構件的順序是Releases -->Snapshots --> 3rd party --> Maven Central。
好多公司處于安全考慮,要求使用用代理通路公網,而nexus經常需要往maven repository中心下載下傳東西,是以需要給nexus的倉庫設定代理。