遠程倉庫的認證安全
1、通常來講,遠程倉庫無須認證就能夠訪問maven
2、但有時候出於安全考慮,須要提供認證信息,爲了防止非法的倉庫訪問,管理員爲每一個倉庫提供了一組用戶名及密碼工具
3、這時爲了讓Maven訪問倉庫內容,就須要配置認證信息測試
如何配置認證信息?ui
1、配置認證信息和配置倉庫信息不一樣,倉庫信息能夠直接配置在POM文件中,可是認證信息必須配置在settings.xml文件中url
2、這是由於POM每每是被提交到代碼倉庫中供全部成員訪問的,而settings.xml通常只放在本機。所以,在settings.xml中配置認證信息更爲安全spa
在settings.xml中配置倉庫認證信息.net
<settings>插件
...命令行
<servers>
<server>
<id>my-proj</id>
<username>repo-user</username>
<password>repo-pwd</password>
</server>
</servers>
...
</settings>
對以上配置信息說明:
1、Maven使用settings.xml文件中並不顯而易見的servers元素及其server子元素配置倉庫認證信息
2、在該配置中倉庫的認證用戶名爲repo-user,認證密碼位repo-pwd
3、這裏的關鍵是id元素,settings.xml中server元素的id必須與POM中須要認證的repository元素的id徹底一致,換句話說,正是這個id將認證信息與倉庫配置聯繫在了一塊兒
私服的一大做用之部署第三方構件
1、第三方構件包括組織內部生成的構件,以及一些沒法從外部倉庫直接獲取的構件
2、不管是平常開發中生成的構件,仍是正式版本發佈的構件,都須要部署到倉庫中,供其餘團隊成員使用
在POM中配置構件部署地址
<project>
...
<distributionManagement>
<repository>
<id>proj-releases</id>
<name>Proj Release Repository</name>
<url>http://192.168.1.100/content/repositories/proj-releases</url>
</repository>
<snapshotRepository>
<id>proj-snapshots</id>
<name>Proj Snapshot Repository</name>
<url>http://192.168.1.100/content/repositories/proj-snapshots</url>
</snapshotRepository>
</distributionManagerment>
...
</project>
對上面的配置進行解釋
1、distributionManagerment包含repository和snapshotRepository子元素,前者表示發佈版本構件的倉庫,後者表示快照版本的倉庫
2、發佈版本倉庫和快照版本倉庫都須要配置id、name和url
3、id爲該遠程倉庫的惟一標識,name是爲了方便人閱讀,關鍵的url表示該倉庫的地址
往遠程倉庫部署構件須要注意什麼?
1、往遠程倉庫部署構件須要認證
2、在settings.xml中建立一個server元素,id與倉庫的id匹配
使用mvn clean deploy
使用mvn clean deploy命令,將項目構建輸出的構件部署到配置對應的遠程倉庫
若是項目當前的版本是快照版本,則部署到快照版本倉庫地址,不然就部署到發佈版本倉庫地址
爲何要區分發布版和快照版呢?
考慮這樣一種場景,小張在開發模塊A的2.1版本,該版本還未正式發佈,與模塊A一同開發的還有模塊B,它由小張的同事季MM開發,B的功能依賴於A。在開發過程當中,小張須要常常將本身最新的構建輸出,交給季MM,供她開發和測試調試,問題是,這個工做如何進行呢?
方案一:
讓季MM本身簽出模塊A的源碼進行構建。這種方法可以確保季MM獲得模塊A的最新構建,不過她不得不去構建模塊A。多了一些版本控制和Maven操做還不算,當構件失敗的時候,她會是一頭霧水,最後不得不找小張解決。顯然,這種方式是低效的
方案二:
重複部署模塊A的2.1版本供季MM下載。雖然小張可以保證倉庫中的構件是最新的,但對於Maven來講,一樣的版本和一樣的座標就意味着一樣的構件。所以,若是季MM在本機的本地倉庫包含了模塊A的2.1版本構件,Maven就不會再對照遠程倉庫進行更新。除非她每次執行Maven命令以前,清除本地倉庫,但這種要求手工干預的作法顯然也是不可取的
方案三:
不停更新版本2.1.1、2.1.2、2.1.3 ... ... 首先,小張和季MM兩人都須要頻繁地更改POM,若是有更多的模塊依賴於模塊A,就會涉及更多的POM更改;其次,大量的版本其實僅僅包含了微小的差別,有時候是對版本號的濫用
那麼如何解決上述問題?
Maven的快照版本機制就是爲了解決上述問題的,在該例中,小張只須要將模塊A的版本設定爲2.1-SNAPSHOT,而後發佈到私服中,在發佈的過程當中,Maven會自動爲構件打上時間戳。好比2.1-20091214.221414-13就表示2009年12月14日22點14分14秒的第13次快照。有了該時間戳,Maven就能隨時找到倉庫中該構件2.1-SNAPSHOT版本最新的文件,這時,季MM配置對於模塊A的2.1-SNAPSHOT版本的依賴,當她構建模塊B的時候,Maven會自動從倉庫中檢查模塊A的2.1-SNAPSHOT的最新構件。當發現有更新時,便進行下載。默認狀況下,Maven天天檢查一次更新 (由倉庫配置的updatePolicy控制),用戶也可使用命令行-U參數強制讓Maven檢查更新,如mvn clean install -U
何時變成發佈版本,爲何發佈版本穩定,快照版本不穩定?
當項目通過完善的測試後須要發佈的時候,就應該將快照版本更改成發佈版本
例如,將2.1-SNAPSHOT更改成2.1,表示該版本已經穩定,且只對應了惟一的構件,相比之下2.1-SNAPSHOT每每對應了大量的帶有不一樣時間戳的構件,這也決定了其不穩定性
對於快照版本的一些建議
快照版本只應該在組織內部的項目或模塊間依賴使用,由於這時,組織對於這些快照版本的依賴具備徹底的理解及控制權
項目不該該依賴於任何組織外部的快照版本依賴,因爲快照版本的不穩定性,這樣的依賴會形成潛在的危險。也就是說,即便項目構建今天是成功的,因爲外部的快照版本依賴實際對應的構件隨時可能變化,項目的構建就可能因爲這些外部的不受控制的因素而失敗
對於快照版本的一些建議
快照版本只應該在組織內部的項目或模塊間依賴使用,由於這時,組織對於這些快照版本的依賴具備徹底的理解及控制權
項目不該該依賴於任何組織外部的快照版本依賴,因爲快照版本的不穩定性,這樣的依賴會形成潛在的危險。也就是說,即便項目構建今天是成功的,因爲外部的快照版本依賴實際對應的構件隨時可能變化,項目的構建就可能因爲這些外部的不受控制的因素而失敗
依賴解析機制歸納
1、當依賴的範圍是system的時候,Maven直接從本地文件系統解析構件
2、根據依賴座標計算倉庫路徑後,嘗試直接從本地倉庫尋找構件,若是發現相應構件,則解析成功
3、在本地倉庫不存在相應構件的狀況下,若是依賴的版本是顯式的發佈版本構件、如1.2、2.1-beta-1d等,則遍歷全部的遠程倉庫,發現後,下載並解析使用
4、若是依賴的版本是RELEASE或LASTEST,則基於更新策略讀取全部遠程倉庫的元數據groupId/artifactId/maven-metadata.xml,將其與本地倉庫的對應元數據合併後,計算出RELEASE或者LASTEST真實的值,而後基於這個真實的值檢查本地和遠程倉庫
5、若是依賴的版本是SNAPSHOT,則基於更新策略讀取全部遠程倉庫的元數據groupId/artifactId/version/maven-metadata.xml,將其與本地倉庫的對應元數據合併後,獲得最新快照版本的值,而後基於該值檢查本地倉庫,或者從遠程倉庫下載
6、若是最後解析獲得的構件版本是時間戳格式的快照,如1.4.1-20091104.121450-121,則複製其時間戳格式的文件至非時間戳格式,如SHAPSHOT,並使用該非時間戳格式的構件
RELEASE和LASTEST版本
這兩個版本分表對應了倉庫中存在的該構件的最新發布版本和最新版本 (包含快照),而這兩個"最新"是基於groupId/artifactId/maven-metadata.xml計算出來的
基於groupId和artifactId的maven-metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus</artifactId>
<versioning>
<latest>1.4.2-SNAPSHOT</latest>
<release>1.4.0</release>
<versions>
<version>1.3.5</version>
<version>1.3.6</version>
<version>1.4.0-SNAPSHOT </version>
<version>1.4.0</version>
<version>1.4.0.1-SNAPSHOT</version>
<version>1.4.1-SNAPSHOT</version>
<version>1.4.2-SNAPSHOT</version>
</versions>
<lastUpdated>20091214221557</lastUpdated>
</versioning>
</metadata>
對該配置進行解釋:
1、該XML文件列出了倉庫中存在的該構件全部可用的版本,同時latest元素指向了這些版本中最新的那個版本,該例中是1.4.2-SNAPSHOT
2、而release元素指向了這些版本中最新的發佈版本,該例中是1.4.0,Maven經過合併多個遠程倉庫及本地倉庫的元數據,就能計算出基於全部倉庫的latest和release分別是什麼,而後再解析具體的構件
在依賴聲明中使用LATEST和RELEASE是不推薦的作法
由於Maven隨時均可能解析到不一樣的構件,可能今天LATEST是1.3.6,明天就成爲1.4.0-SNAPSHOT了,且Naven不會明確告訴用戶這樣的變化。當這種變化形成構建失敗的時候,發現問題會變得比較困難。RELEASE由於對應的是最新發布版構建,還相對可靠,LASTEST就很是不可靠了
爲此,Maven 3再也不支持在插件配置中使用LATEST和RELEASE。若是不設置插件版本,其效果就和RELEASE同樣,Maven只會解析最新的發佈版本構件。不給過即便這樣,也還存在潛在的問題,好比某個依賴的1.1版本與1.2版本可能發生一些接口的變化,從而致使當前Maven構建的失敗
基於groupId、artifactId和version的maven-metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus</artifactId>
<version>1.4.2-SNAPSHOT</version>
<versioning>
<snapshot>
<timestap>20091214.221414</timestap>
<buildNumber>13</buildNumber>
</snapshot>
<lastUpdated>20091214221558</lastUpdated>
</versioning>
</metadata>
對該配置進行說明:
1、該XML文件的snapshot元素包含了timesstamp和buildNumber兩個子元素,分別表明了這一快照的時間戳和構建號
2、基於這兩個元素能夠獲得該倉庫中此快照的最新構件版本實際爲
1.4.2-20091214.221414-13,經過合併全部遠程倉庫和本地倉庫的元數據,Maven就能知道全部參控股中該構件的最新快照
3、注意,倉庫的元數據並非永遠正確的,有時候當用戶發現沒法解析某些構件,或者解析獲得錯誤構件的時候,就有多是出現了倉庫元數據錯誤,這時就須要手工地,或者使用工具 (如Nexus) 對其進行修復
什麼是鏡像?
若是倉庫X能夠提供倉庫Y存儲的全部內容,那麼就能夠認爲X是Y的一個鏡像
換句話說,任何一個能夠從倉庫Y得到的構件,都可以從它的鏡像中獲取
舉個例子,http://maven.net.cn/content/groups/public是中央倉庫http://repo1.maven.org/maven2在中國的鏡像,因爲地理位置的因素,該鏡像每每可以提供比中央倉庫更快的服務
所以,能夠配置Maven使用該鏡像來替代中央倉庫
配置中央倉庫鏡像settings.xml
<settings>
...
<mirrors>
<mirror>
<id>maven.net.cn</id>
<name>one of the central mirrors inChina</name>
<url>http://maven.net.cn/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
...
</setting>
對上面的配置進行解釋:
1、在該例中,<mirrorOf>的值爲central,表示該配置爲中央倉庫的鏡像,任何對於中央倉庫的請求都會轉至該鏡像
2、用戶也可使用一樣的方法配置其餘倉庫的鏡像
3、另外三個元素id、name、url與通常倉庫配置無異,表示該鏡像倉庫的惟一標識符、名稱以及地址。相似的,若是該鏡像須要認證,也能夠基於該id配置倉庫認證
一個鏡像的常見用法
關於鏡像的一個更爲常見的用法是結合私服,因爲私服能夠代理任何外部的公共倉庫(包括中央倉庫),所以,對於組織內部的Maven用戶來講,使用一個私服地址就等於使用了全部須要的外部倉庫,這能夠將配置集中到私服,從而簡化Maven自己的配置。
配置私用私服做爲鏡像
<settings>
...
<mirrors>
<mirror>
<id>internal-repository </id>
<name>Internal Repository Manager</name>
<url>http://192.168.1.100/maven2</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</setting>
解釋上面的配置:
1、該例中<mirrorOf>的值爲星號,表示該配置是全部Maven倉庫的鏡像,任何對於遠程倉庫的請求都會被轉至http://192.168.1.100/maven2/,若是該鏡像倉庫須要認證,則配置一個id爲internal-repository的<server>便可
使用很是快速的OSChina的遠程倉庫做爲鏡像替代默認的中央倉庫
<settings>
...
<mirror>
<id>CN</id>
<name>OSChina Central</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
...
</settings>
更復雜的<mirrorOf>配置
爲了知足一些複雜的需求,Maven還支持更高級的鏡像配置:
1、<mirrorOf>*</mirrorOf>:匹配全部遠程倉庫
2、<mirrorOf>external:*</mirrorOf>:匹配全部遠程倉庫,使用localhost的除外,使用file://協議的除外,也就是說,匹配全部不在本機上的遠程倉庫
3、<mirrorOf>repo1,repo2</mirrorOf>:匹配倉庫repo1和repo2,使用逗號分割多個遠程倉庫
4、<mirrorOf>*,!repo1</mirrorOf>:匹配全部遠程倉庫,repo1除外,使用感嘆號將倉庫從匹配中排除
有一點須要注意
須要注意的是,因爲鏡像倉庫徹底屏蔽了被鏡像倉庫,當鏡像倉庫不穩定或者中止服務的時候,Maven仍將沒法訪問被鏡像倉庫,於是將沒法下載構件