一個Maven項目發布版本號用version 編碼,用來分組和排序發布。Maven中的版本包含了以下部分:主版本,次版本,增量版本,和限定版本號。一個版本中,這些部分對應如下的格式:
<major version>.<minor version>.<incremental version>-<qualifier>
例如:版本“1.3.5”由一個主版本1,一個次版本3,和一個增量版本5。而一個版本“5”只有主版本5,沒有次版本和增量版本。限定版本用來標識里程碑構建:alpha和beta發布,限定版本通過連字符與主版本,次版本或增量版本隔離。例如,版本“1.3-beta-01”有一個主版本1,次版本3,和一個限定版本“beta-01”。
當你想要在你的POM中使用版本界限的時候,保持你的版本號與標準一致十分重要。在版本界限,允許你聲明一個帶有版本界限的依賴,只有你遵循標準的時候該功能才被支持。因為Maven根據本節中介紹的版本號格式來對版本進行排序。
如果你的版本號與格式<主版本>.<次版本>.<增量版本>-<限定版本>相匹配,它就能被正確的比較;“1.2.3”將被評價成是一個比“1.0.2”更新的構件,這種比較基于主版本,次版本,和增量版本的數值。如果你的版本發布號沒有符合本節介紹的標準,那么你的版本號只會根據字符串被比較;“1.0.1b”和“1.2.0b”會使用字符串比較。
1. 版本構建號
我們還需要對版本號的限定版本進行排序。以版本號“1.2.3-alpha-2”和“1.2.3-alpha-10”為例,這里“alpha-2”對應了第二次alpha構建,而“alpha-10”對應了第十次alpha構建。雖然“alpha-10”應該被認為是比“alpha-2”更新的構建,但Maven排序的結果是“alpha-10”比“alpha-2”更舊,問題的原因就是我們剛才討論的Maven處理版本號的方式。
Maven會將限定版本后面的數字認作一個構建版本。換句話說,這里限定版本是“alpha”,而構建版本是2。雖然Maven被設計成將構建版本和限定版本分離,但目前這種解析還是失效的。因此,“alpha-2”和“alpha-10”是使用字符串進行比較的,而根據字母和數字“alpha-10”在“alpha-2”前面。要避開這種限制,你需要對你的限定版本使用一些技巧。如果你使用“alpha-02”和“alpha-10”,這個問題就消除了,一旦Maven能正確的解析版本構建號之后,這種工作方式也還是能用。
2. SNAPSHOT版本
Maven版本可以包含一個字符串字面量來表示項目正處于活動的開發狀態。如果一個版本包含字符串“SNAPSHOT”,Maven就會在安裝或發布這個組件的時候將該符號展開為一個日期和時間值,轉換為UTC(協調世界時)。例如,如果你的項目有個版本為“1.0-SNAPSHOT”并且你將這個項目的構件部署到了一個Maven倉庫,如果你在UTC2008年2月7號下午11:08部署了這個版本,Maven就會將這個版本展開成“1.0-20080207-230803-1”。換句話說,當你發布一個snapshot,你沒有發布一個軟件模塊,你只是發布了一個特定時間的快照版本。
那么為什么要使用這種方式呢?SNAPSHOT版本在項目活動的開發過程中使用。如果你的項目依賴的一個組件正處于開發過程中,你可以依賴于一個SNAPSHOT版本,在你運行構建的時候Maven會定期的從倉庫下載最新的snapshot。類似的,如果你系統的下一個發布版本是“1.4”你的項目需要擁有一個“1.4-SNAPSHOT”的版本,之后它被正式發布。
作為一個默認設置,Maven不會從遠程倉庫檢查SNAPSHOT版本,要依賴于SNAPSHOT版本,用戶必須在POM中使用repository
和pluginRepository
元素顯式的開啟下載snapshot的功能。
當發布一個項目的時候,你需要解析所有對SNAPSHOT版本的依賴至正式發布的版本。如果一個項目依賴于SNAPSHOT,那么這個依賴很不穩定,它隨時可能變化。發布到非snapshot的Maven倉庫(如http://repo1.maven.org/maven2)的構件不能依賴于任何SNAPSHOT版本,因為Maven的超級POM對于中央倉庫關閉了snapshot。SNAPSHOT版本只用于開發過程。
3. LATEST 和 RELEASE 版本
當你依賴于一個插件或一個依賴,你可以使用特殊的版本值LATEST或者RELEASE。LATEST是指某個特定構件最新的發布版或者快照版(snapshot),最近被部署到某個特定倉庫的構件。RELEASE是指倉庫中最后的一個非快照版本。總得來說,設計軟件去依賴于一個構件的不明確的版本,并不是一個好的實踐。如果你處于軟件開發過程中,你可能想要使用RELEASE或者LATEST,這么做十分方便,你也不用為每次一個第三方類庫新版本的發布而去更新你配置的版本號。但當你發布軟件的時候,你總是應該確定你的項目依賴于某個特定的版本,以減少構建的不確定性,免得被其它不受你控制的軟件版本影響。如果無論如何你都要使用LATEST和RELEASE,那么要小心使用。
Maven 2.0.9之后,Maven在超級POM中鎖住了一些通用及核心Maven插件的版本號,以將某個特定版本Maven的核心Maven插件組標準化。這個變化在Maven 2.0.9中被引入,為Maven構建帶來了穩定性和重現性。在Maven 2.0.9之前,Maven會自動將核心插件更新至LATEST版本。這種行為導致了很多奇怪現象,因為新版本的插件可能會有一些bug,甚至是行為變更,這往往使得原來的構建失敗。當Maven自動更新核心插件的時候,我們就不能保證構建的重現性,因為插件隨時都可能從中央倉庫更新至一個新的版本。從Maven 2.0.9開始,Maven從根本上鎖住了一組核心插件的版本。非核心插件,或者說沒有在超級POM中指定版本的插件仍然會使用LATEST版本去從倉庫獲取構件。由于這個原因,你在構件中使用任何一個自定義非核心插件的時候,都應該顯式的指定版本號。