上面提到的某些名稱似乎建立得不夠充分,而其他一些則可能需要討論其使用方式。 考慮到這一點,我決定在自己的博客文章中探索每種解決方案,并設定了提供足夠信息的目標,以便人們可以選擇最有效的方法。
第一篇文章探討了Maven快照和發行版依賴關系。 第二篇文章介紹了TeamCity提供的工件和快照依賴關系,第三篇也是最后一部分將介紹TeamCity Artifactory插件提供的工件和構建依賴關系。
內部和外部依賴性
通過簽出整個代碼庫并從頭開始構建應用程序,構建過程可以完全隔離地運行。 對于項目,將相關的二進制依賴項(如果有)與項目源一起保存在VCS中就是這種情況。 但是,在許多其他情況下,構建腳本依賴于某種內部或外部依賴性 。
內部依賴關系由我們自己的代碼來滿足,在代碼中我們可以完全控制該項目,該項目可以分為多個模塊或子項目。 外部依賴關系由其他人的代碼(我們無法控制)來滿足,我們可以使用它或將其用作客戶端。 這可以是第三方庫(例如Spring)或另一個團隊開發的組件。
這種區別非常重要,因為內部和外部依賴項通常伴隨著不同的發布和升級周期:內部依賴項可以每小時進行一次修改,重建和更新,而外部依賴項的發布周期顯著變慢,因為用戶應用更新的頻率更低,如果有的話。 這主要是由于內部依賴項受我們自己控制,并且受到特定項目或模塊的限制而產生了范圍狹窄的影響,而外部依賴項只能按原樣使用,其影響可能是公司或全球范圍。 ,它們不受任何項目的限制,可以在任何地方使用。 自然,這需要更高的發行版穩定性,兼容性和成熟度標準,因此發行和更新周期較慢。
“內部與外部”相關性特征的另一方面表現為在構建腳本中如何指定其版本。 內部依賴關系通常使用快照版本定義,而外部依賴關系則使用發行版本。 “快照”和“發布”版本的定義是Maven提出的,Maven開創了通過構建工具管理依賴項的想法。 如果您熟悉自動依賴項管理,請隨時跳過以下部分,其中提供了有關其工作原理的快速概述。
自動依賴管理
在Maven中,依賴關系是在構建腳本中聲明性地指定的,此方法隨后是一種較新的構建工具,例如Gradle , Buildr和sbt 。
Maven:
<dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>1.8.6</version><scope>compile</scope>
</dependency>
搖籃:
compile "org.codehaus.groovy:groovy-all:1.8.6"
生成器:
compile.with "org.apache.axis2:axis2:jar:1.6.1"
sbt:
libraryDependencies += "org.twitter4j" % "twitter4j-core" % "2.2.5"
每個依賴項都通過其坐標和范圍來標識。 坐標明確指定所使用的庫和版本,而范圍則定義其在編譯或測試調用等構建任務中的可見性和可用性。
例如, "compile org.codehaus.groovy:groovy-all:1.8.6"
將為版本"1.8.6"
指定一個Groovy "org.codehaus.groovy:groovy-all"
發行版,用于源代碼編譯和測試調用。 將范圍切換到“測試”或“運行時”將把庫的可見性分別縮小到僅測試或僅運行時。
當構建開始時,依賴關系要么位于由構建工具管理的本地工件存儲庫中(類似于瀏覽器緩存),要么從遠程存儲庫(無論是公共存儲庫還是私有存儲庫)下載,例如Maven Central , Artifactory或Nexus 。 然后,構建工具根據其作用域將解析出的工件添加到相應的類路徑中。 組裝構建工件(例如"*.war"
或"*.ear"
檔案時,所有必需的依賴項也會正確處理和打包。
盡管依賴關系管理似乎是幾乎所有構建中必不可少的部分,但并非所有構建工具都為其提供內置支持: Ant和MSBuild缺少此功能,后來Ivy和NuGet在一定程度上解決了這一差距。 但是,與Maven相比,Ivy的采用速度較慢,而NuGet是僅.NET的工具。 隨著時間的流逝,Maven工件存儲庫和Maven Central已經成為分布和共享Java工件的事實上的機制。 能夠使用Maven存儲庫解析和部署這些資源已成為所有較新的Java構建工具的“必備”能力。
發行和快照依賴性
如前所述,內部依賴關系通常使用快照版本定義,而外部依賴關系則使用發行版本。 讓我們先看一下發行版本,因為它們更容易推論。
發行依賴關系是具有固定版本號的依賴關系 ,例如Groovy發行版的"1.8.6"
版本。 無論構建使用什么工件存儲庫,并且無論何時嘗試查找此依賴項,總是希望它解析出完全相同的工件。 這是發布依賴項的主要原理: “相同版本=相同工件” 。 由于這個事實,構建工具不會在發現發布依賴關系更新后對其進行檢查,并且僅在清空本地緩存后才會重新下載工件。 當然,所有這一切都是有道理的,因為我們永遠都不會期望找到帶有相同版本號的同一個庫的不同工件!
快照依賴關系是不同的,因此,處理起來很棘手。 快照依賴項版本以特殊的"-SNAPSHOT"
關鍵字結尾,例如"3.2.0-SNAPSHOT"
。 該關鍵字向構建工具發出信號,以通過遠程存儲庫定期檢查工件以進行更新; 默認情況下,Maven 每天執行一次此檢查。 快照依賴關系的功能,那么,是依靠別人的工作正在進行中(想想“每日構建”):當產品開發移動從版本"X"
到版本"X+1"
的模塊版本"X+1-SNAPSHOT"
。
快照相關性不確定性
如果發布依賴關系的主要原則是“相同版本=相同工件” (版本“ X”發布的庫,其工件在世界范圍內永遠相同),則快照依賴關系的原則是“相同版本=不斷更新”神器” 。 這種方法的好處是,它可以檢索頻繁的更新,而無需產生非常不切實際的每日發布。 但是,它的缺點是不確定性–在構建腳本中使用快照依賴關系會使得更難知道在特定構建執行過程中使用了哪個版本。 我的"maven-about-plugin"
將文本“ about”文件存儲在每個快照工件中,以便更好地標識其來源,例如VCS版本和內部版本號; 這可能會有所幫助,但只能解決一半問題。
作為其定義的移動目標,快照依賴項不允許我們確定我們所依賴的版本,因此很難實現構建的可復制性。 同樣,在一系列構建或構建管道中(當完成的構建觸發了后續構建的調用時),初始管道步驟所產生的工件不一定會被關閉的那些消耗,因為此后可能會被其他構建過程長時間覆蓋,與此同時。
在這種情況下,一種可能的方法是使用時間戳 鎖定構建腳本中的依賴項版本,使其成為"3.2.0-20120119.134529-1"
而不是"3.2.0-SNAPSHOT"
。 這有效地使快照依賴關系與發行依賴關系相同,并禁用了自動更新機制,從而即使在沒有時間戳的情況下也無法使用最新版本,除非更新了時間戳。
如您所見,可以在有意義的地方使用快照依賴關系,但應謹慎并小劑量進行。 如果可能,最好為每個可重用組件管理一個單獨的發行生命周期,并讓其客戶端使用定期更新的發行依賴關系。
摘要
本文概述了Java構建工具對自動依賴項的管理,并介紹了Maven版本和快照依賴項。 它還解釋了快照依賴項的優勢如何在構建可復制性和構建管道的背景下值得商de。
以下博客文章將探討TeamCity構建鏈和Artifactory構建隔離,這些構建隔離允許在整個構建鏈中使用一致,可重現和最新的快照版本,而無需在構建腳本中鎖定其時間戳。 還有更多!
參考:來自Goldman ++博客的JCG合作伙伴 Evgeny Goldin的Maven Build Dependencies 。
翻譯自: https://www.javacodegeeks.com/2012/05/maven-build-dependencies.html