在Maven中权衡构建再现性和中间依赖项更新

在Maven中权衡构建再现性和中间依赖项更新,maven,Maven,有时,在我们的项目中会出现使用来指定依赖关系的问题 扩展的“三段论”是这样的: 应用程序X具有内部(我们组织的)依赖关系Y 依赖项Y有一个外部依赖项Z(例如org.apache.httpcomponents:httpclient的g:a) Dependency Z的提供者非常擅长在major.minor版本号中提供向后兼容性(例如,对于httpclient,4.5.1到4.5.2可以可靠地假定只包含bug修复,不包含API更改) 如果应用程序X想要利用对依赖项Z的更新,它不应该需要依赖项Y的新

有时,在我们的项目中会出现使用来指定依赖关系的问题

扩展的“三段论”是这样的:

  • 应用程序X具有内部(我们组织的)依赖关系Y
  • 依赖项Y有一个外部依赖项Z(例如
    org.apache.httpcomponents:httpclient的
    g:a
  • Dependency Z的提供者非常擅长在
    major.minor
    版本号中提供向后兼容性(例如,对于
    httpclient
    4.5.1
    4.5.2
    可以可靠地假定只包含bug修复,不包含API更改)
  • 如果应用程序X想要利用对依赖项Z的更新,它不应该需要依赖项Y的新构建
  • 事实上,我们还有依赖项Y1、Y2、Y3等,它们都提供类似的功能(不同Web服务的客户端),并且依赖于相同的
    major.minor
    版本的
    httpclient
    ,并且对
    增量版本漠不关心(除了任何相关的bug修复)
因此,依赖项Y、Y1、Y2等可以将其依赖项Z的版本指定为允许应用程序x“升级”的范围(例如
httpclient:[4.5,4.6)
,以表示“任何
httpclient的
4.5.x
版本就足够了”通过指定依赖项Z的托管版本(即,在内部将版本本身修复为依赖项Y标识的所提供范围内的某个内容),来更新依赖项Z的增量版本

另一种选择似乎是依赖关系Y(和相关)继续指定依赖关系Z的特定版本(已知的最新版本,但可能稍有过时)作为不范围的
4.5.inc
,因此当依赖关系Z提供较新版本时,应用程序X具有以下选项:

  • 内部管理依赖项Z的版本(即强制最新版本覆盖依赖项Y的首选版本)
  • 更新Dependency Y声明的Dependency Z版本,重新生成,对所有Y1、Y2、Y3等执行相同操作,然后更新App X版本的Dependency Y、Y1、Y2等
  • 但是,.#1的“我在实践中将依赖项Z视为灵活的,但不愿意在依赖项Y的
    pom.xml
    中声明这一点”似乎是不诚实的

    #2的“滴流升级”是当前的做法,也是一个难点。它似乎没有什么价值,因为依赖项Y系列的代码没有内部更改,只是更新了依赖项

    关于上述问题的意见:

  • “三段论”的建议似乎违反了“不使用版本范围”的思想流派。虽然应用程序X具有“构建再现性”,但依赖性Y不一定……尽管范围有限,但它可能是可以接受的
  • 我遇到的“不要使用版本范围”的帖子似乎支持备选方案-1
  • 备选方案2(当前实践)是否仅仅是确保应用程序X和应用程序Y中的“再现性”的必要条件
  • 所以,关键问题是:有没有一个我忽略的选项或替代方案可以避免感受到“滴流升级”和“构建再现性”之间的紧张关系


    理想情况下,它会明确指出:“使用版本
    g:a:maj.min.inc构建依赖关系Y,但保持传递性不明确,并接受任何
    g:a:maj.min.?
    version down.。

    我可以看到两个选项

    如果Y仅在X或类似的上下文中使用,您可以将依赖项向上移动到Z级别-将其定义为Y中提供的
    (具有版本范围),以及X中具有版本范围的一级依赖项。这样,Y中的依赖项实际上会说明您想要它做什么(请将该范围中的最新版本),并且在每次构建X时,它都会对最新版本感到满意


    如果不是这样的话,Y将使用某些版本的Z构建,现在可能不是最新版本。如果您确实想要最新版本,现在唯一的选择是覆盖(或滴流更新)正如您所说。这并不是不诚实的:Y的.pom文件中的范围符号将向X实现者暗示,如果需要,它的依赖性实际上可能需要被覆盖。

    这是一个好问题……正如您所说,有两种方法,但我不明白如何将它们合并为第三种方法。构建中使用的依赖性消费者的可传递依赖项也是一样的……你可以从Y中去掉Z依赖项,X将完全依赖于Z,但这也不是一个好的实践……根据我的经验(这里描述:)我不再认为范围是一种选择,而是在“Maven版本范围是邪恶”的情况下进行了很长一段时间。KooAID。我还没有决定是否继续做“涓涓细流”。或者,如果已知Z有解决相关问题的修复程序,则仅更新Y的Z的声明版本号。使用提供的
    是有问题的。我快速试用使我陷入了项目Y依赖于Z的情况(标记为提供的
    )。如果项目X依赖于Y,但不直接依赖于Z,则项目X需要将项目Z显式声明为依赖项,否则它将无法编译。这消除了“可传递”的便利性通过要求在不需要指定Z的地方指定Z来实现依赖关系。滴流或让项目覆盖是一种方法。