在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
可以可靠地假定只包含bug修复,不包含API更改)4.5.2
- 如果应用程序X想要利用对依赖项Z的更新,它不应该需要依赖项Y的新构建
- 事实上,我们还有依赖项Y1、Y2、Y3等,它们都提供类似的功能(不同Web服务的客户端),并且依赖于相同的
版本的major.minor
,并且对httpclient
增量版本漠不关心(除了任何相关的bug修复)
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来实现依赖关系。滴流或让项目覆盖是一种方法。