Maven父POM:循环依赖

Ale*_*ler 5 circular-dependency dependency-management maven

我们有一个模块化项目,大约有10个工件:

parent
 +- artifact1
 +- artifact2
 +- artifact3
 +- ...
 +- artifact10
Run Code Online (Sandbox Code Playgroud)

此外,一些工件彼此之间存在依赖关系:

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

artifact2
 +-> artifact3

artifact4
 +-> artifact3

artifact4
 +-> artifact5

artifact5
 +-> artifact6
Run Code Online (Sandbox Code Playgroud)

我们目前的设置如下:

  • parent是包含父POM的工件.
  • 这个父POM定义了所有必要的依赖项(如Spring,JPA,...).
  • 我们所有的工件也都定义了.
  • 我们的工件将父工件引用为 - 说明显而易见的 - 父级.
  • 只有父POM定义版本.所有其他POM都没有.

我们使用带有三个数字的版本控制方案:

<major version>.<minor version>.<patch level>
Run Code Online (Sandbox Code Playgroud)

例如:

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)
Run Code Online (Sandbox Code Playgroud)

问题:

一旦我们更改了工件的版本(例如: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 ...
Run Code Online (Sandbox Code Playgroud)

工件目录(在方括号中;与工件版本一起)彼此独立,即为方便起见,它们仅在公共根目录(".")中.每个工件都有自己的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>
Run Code Online (Sandbox Code Playgroud)

场景:

  • 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.=>恶性循环.

(注意:工件名称是为了简单起见.)

Mar*_*szS 1

建议

为了简化依赖项配置,请使用版本范围

例如,工件A需要B版本为 的工件0.1.0。将依赖关系配置为 range <version>[0.1.0, 0.2.0)</version>

这意味着A需要B版本大于或等于 0.1.0 且小于 0.2.0(因此所有修补程序都适合此工件)。

这很有帮助,因为当发布修补程序时,无需更改工件A依赖项。只需重建父项目,修补程序B就会附加到项目中A

此技术需要在发布修补程序时释放父项目对于父项目,我的意思是像带有库的 WAR 或 EAR,或者包含所有工件的分发存档。

更多:3.4.3。依赖项版本范围