簡體   English   中英

Maven父POM:循環依賴

[英]Maven parent POM: Circular dependencies

我們有一個模塊化項目,大約有10個工件:

parent
 +- artifact1
 +- artifact2
 +- artifact3
 +- ...
 +- artifact10

此外,一些工件彼此之間存在依賴關系:

artifact1
 +-> artifact2
 +-> artifact3
 +-> ...
 +-> artifact10

artifact2
 +-> artifact3

artifact4
 +-> artifact3

artifact4
 +-> artifact5

artifact5
 +-> artifact6

我們目前的設置如下:

  • parent是包含父POM的工件。
  • 這個父POM定義了所有必要的依賴項(如Spring,JPA,...)。
  • 我們所有的工件也都定義了。
  • 我們的工件將父工件引用為 - 說明顯而易見的 - 父級。
  • 只有父POM定義版本。 所有其他POM都沒有。

我們使用帶有三個數字的版本控制方案:

<major version>.<minor version>.<patch level>

例如:

0.1.0-SNAPSHOT (a young artifact in development)
0.1.0 (the same artifact once it has been released)
0.1.1 (the same artifact after a hotfix)

問題:

一旦我們更改了工件的版本(例如:0.1.0 => 0.1.1),我們的父工件版本(12.7.3)需要更新,因為它引用了舊的工件版本(0.1.0)。 由於我們在父POM(0.1.0 => 0.1.1)中更改了此引用,因此我們也需要增加父POM的版本(12.7.3 => 12.7.4)。 現在,我們的工件仍然引用了先前的父版本(12.7.3),即我們需要再次更新它...這是循環的。

解決這種循環親子關系的最佳方法是什么? 我們可以從父POM中刪除我們自己的依賴項,並在所有其他工件的POM中定義它們的版本,但這意味着我們需要在依賴項更改后更新所有工件。

編輯

包含我們工件的簡化目錄結構:

.
├── [api:0.14.0-SNAPSHOT]
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java ...
│       │   └── webapp ...
│       └── test
├── [dao:1.21.0-SNAPSHOT]
│   ├── pom.xml
│   └── src
│       ├── main ...
│       └── test ...
├── [parent:0.11.0-SNAPSHOT]
│   ├── pom.xml
│   └── src
│       ├── main ...
│       └── test ...
├── [pdf-exporter:0.2.0-SNAPSHOT]
│   ├── pom.xml
│   └── src
│       ├── main ...
│       └── test ...
├── [docx-exporter:0.3.0-SNAPSHOT]
│   ├── pom.xml
│   └── src
│       ├── main ...
│       └── test ...
├── [exporter-commons:0.9.0-SNAPSHOT]
│   ├── pom.xml
│   └── src
│       ├── main ...
│       └── test ...
└── [security:0.6.0-SNAPSHOT]
    ├── pom.xml
    └── src
        ├── main ...
        └── test ...

工件目錄(在方括號中;與工件版本一起)彼此獨立,即為方便起見,它們僅在公共根目錄(“。”)中。 每個工件都有自己的git存儲庫。 “api”是部署在應用程序服務器上的工件。 所有工件都像這樣引用“父”(在開發期間):

<parent>
    <groupId>com.acme</groupId>
    <artifactId>parent</artifactId>
    <version>0.11.0-SNAPSHOT</version>
</parent>

<artifactId>api</artifactId>
<version>0.14.0-SNAPSHOT</version>

場景:

  • exporter-commons獲得更新:0.9.0-SNAPSHOT => 0.9.1-SNAPSHOT。
  • docx-exporter和pdf-exporter引用exporter-commons沒有版本,即不需要更改。
  • 父需要更新以反映exporter-commons的更新:0.11.0-SNAPSHOT => 0.12.0-SNAPSHOT。

問題:api:0.14.0-SNAPSHOT引用父:0.11.0-SNAPSHOT。 api:0.14.0-SNAPSHOT然后更新為引用父:0.12.0-SNAPSHOT。 api:0.14.0-SNAPSHOT變為api:0.15.0-SNAPSHOT。 但是父級中的pom.xml:0.12.0-SNAPSHOT引用api:0.14.0-SNAPSHOT。 =>惡性循環。

(注意:工件名稱是為了簡單起見。)

建議

為簡化依賴配置,請使用版本范圍

例如,工件A需要版本為0.1.0工件B 將依賴項配置為范圍<version>[0.1.0, 0.2.0)</version>

這意味着A要求B的版本大於或等於0.1.0且小於0.2.0(因此所有修補程序都適用於此工件)。

這有幫助,因為當發布修補程序時,不需要更改工件A依賴項。 只需重建父項目和hotfixed B將附加到項目A

這個技術需要在發布修補程序時釋放父項目 。父項目我的意思是像WAR一樣考慮庫或EAR,或者包含內部所有工件的分發存檔。

更多: 3.4.3。 依賴版本范圍

Maven中混淆的一個主要原因是parent pom實際上可以包含兩種不同類型的關系:

  • 親子關系:
    • 在每個子元素的<parent>標記內聲明一次
    • 繼承pom.xml中聲明的插件,依賴項,屬性,版本等
  • 聚合器 - 子模塊關系:
    • 通過<modules>標簽在頂級pom中聲明一次
    • 通過cmd行傳遞的目標(例如mvn clean install )將傳遞給子模塊

如果所有模塊保持在同一版本(即始終從頂層執行發布),則此區別無關緊要。 但是只要版本開始碎片化(即釋放一個子模塊而不釋放另一個子模塊),就有必要為每個任務創建2個獨立的pom。

project/
  parent/
    parent_pom.xml      # declare dependency versions as ranges [0.1.0, 0.2.0)
  children/
    aggregator_pom.xml  # <modules> section lists api/dao/etc
    api/
      pom.xml           # declare parent_pom as parent
    dao/
      pom.xml           # declare parent_pom as parent

為什么需要這種復雜的結構?

為什么不直接使用MariuszS建議在頂級父級使用范圍?

想象一下, api一個基本組件非常穩定。 如果可以避免,您不想重建或重新發布它。

同時,讓我們說兩個相互依賴的組件,如pdf-exporterdocs ,你經常發布和/或分支,以便你經常更改版本范圍:0.1.x - > 0.2.x - > 0.3.x等。

然后你會被迫修改和釋放你的父pom以反映pdf-exporterdocs之間的關系,但你不一定要發布api因為它不關心這些變化。 因此,需要將父親放在一邊並確保釋放它不會觸發api子模塊的不必要的重新釋放。

如果有一個共同的根模塊(“父”),所有其它模塊(以下簡稱“兒”)依靠, 沒有一個孩子應該在由母公司依賴。

這是因為Maven以一種非常簡單的方式工作:要構建一個模塊, 首先要構建它所依賴的所有模塊(使用傳遞閉包模型),這些模塊尚未構建。 如果你有一個循環依賴,你最終會遇到這樣的情況:為了構建A,你必須首先建立A。 這很瘋狂,顯然無法以有用的方式運作。

但是,您也可以讓父母將其子項作為子模塊。 這是一種不同的, 不可繼承的關系,它導致子模塊在超級模塊之后構建。 這樣可行。 使超級模塊的子模塊與超級模塊沒有其他關系也是完全合理的。

簡而言之,無論您將模塊安排在磁盤上還是存儲庫中, 都不要引入循環依賴 (我已經看到它認為循環依賴應該在邏輯上將一組模塊轉換為單個模塊,因為這是明確定義正確包含運算符操作的唯一方法。我不確定我是否完全贊同,但這並非完全錯誤......)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM