Maven 父 POM : Circular dependencies

标签 maven dependency-management circular-dependency

我们有一个包含大约 10 个 Artifact 的模块化项目:

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

此外,一些 Artifact 之间存在依赖关系:
artifact1
 +-> artifact2
 +-> artifact3
 +-> ...
 +-> artifact10

artifact2
 +-> artifact3

artifact4
 +-> artifact3

artifact4
 +-> artifact5

artifact5
 +-> artifact6

我们当前的设置如下所示:
  • parent 是包含父 POM 的 Artifact 。
  • 这个父 POM 在 .
  • 我们所有的 Artifact 也都在 中定义。
  • 我们的 Artifact 将父 Artifact 引用为 - 说明显而易见的 - 父级。
  • 只有父 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)
    

    问题:

    一旦我们更改了 Artifact 的版本(例如:0.1.0 => 0.1.1),我们的父 Artifact 版本(12.7.3)需要更新,因为它引用了旧的 Artifact 版本(0.1.0)。由于我们在父 POM 中更改了此引用 (0.1.0 => 0.1.1),因此我们也需要增加父 POM 的版本 (12.7.3 => 12.7.4)。现在,我们的 Artifact 仍然引用以前的父版本(12.7.3),即我们需要再次更新它......这是循环的。

    解决这种循环父子关系的最佳方法是什么?我们可以从父 POM 中删除我们自己的依赖项,并在所有其他 Artifact 的 POM 中定义它们的版本,但这意味着一旦依赖项发生更改,我们就需要更新所有 Artifact 。

    编辑

    包含我们的 Artifact 的简化目录结构:
    .
    ├── [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 ...
    

    Artifact 目录(在方括号中;与 Artifact 版本一起)彼此独立,即为了方便起见,它们仅位于公共(public)根目录(“.”)中。每个 Artifact 都有自己的 git 存储库。 “api”是部署在应用程序服务器上的 Artifact 。所有 Artifact 都像这样引用“父级”(在开发期间):
    <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 无版本,即无需更改。
  • parent 需要更新以反射(reflect) exporter-commons 的更新:0.11.0-SNAPSHOT => 0.12.0-SNAPSHOT。

  • 问题:api:0.14.0-SNAPSHOT 引用 parent:0.11.0-SNAPSHOT。 api:0.14.0-SNAPSHOT 然后更新为引用 parent:0.12.0-SNAPSHOT。 api:0.14.0-SNAPSHOT 变为 api:0.15.0-SNAPSHOT。但是 parent:0.12.0-SNAPSHOT 中的 pom.xml 引用了 api:0.14.0-SNAPSHOT。
    => 恶性循环。

    (注意:为简单起见, Artifact 名称是虚构的。)

    最佳答案

    建议

    为了简化依赖配置,请使用 versions ranges .

    例如 Artifact A需要神器B与版本 0.1.0 .将依赖项配置为范围 <version>[0.1.0, 0.2.0)</version> .

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

    这会有所帮助,因为发布修补程序时,无需更改 Artifact A依赖关系。只需重建父项目并修复 B将附加到项目A
    此技术需要在发布修补程序时释放父项目 通过父项目,我的意思是类似于带有库或 EAR 的 WAR,或带有所有 Artifact 的 Distribution Archive。

    更多:3.4.3. Dependency Version Ranges

    关于Maven 父 POM : Circular dependencies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21416703/

    相关文章:

    java - 使用maven下载javax.json

    go - 如何将 godep 与测试包一起使用

    java - GWT:Maven 错误:jar 必须为 'pom' 才能导入托管依赖项

    c++ - 物理引擎的循环模板类型名依赖

    javascript - AngularJS 指令范围内的重复元素引发 TypeError : Converting circular structure to JSON

    javascript - 交叉依赖的默认参数未定义

    java - 在 Eclipse 中使用 maven-release-plugin

    tomcat - Jenkins 没有通过 maven-antrun 运行 Catalina.bat

    java - 有没有办法在没有安装maven的情况下从自动化庄园中的pom.xml下载依赖项?

    java - 多模块 gradle 构建 jar