来源Oracle® Fusion Middleware Developing Applications Using Continuous Integration
在使用Maven时,理解如何使用版本号是非常重要的。一个经过深思熟虑(well thought out)的策略可以大大简化你的依赖管理工作量。本文介绍了关于版本号在Maven中如何工作的重要概念。
包含以下三个部分:
- Maven版本号如何工作
- SNAPSHOT限定符
- 版本范围引用
1 Maven版本号如何工作
Maven的版本管理方案(scheme)使用以下的标准:
- MajorVersion
- MinorVersion
- IncrementalVersion
- BuildNumber
- Qualifier
例如:
- MajorVersion: 1.2.1
- MinorVersion: 2.0
- IncrementalVersion: 1.2-SNAPSHOT
- BuildNumber: 1.4.2-12
- Qualifier: 1.2-beta-2
具有限定符的版本,旧于没有限定符的(发布版本),例如:1.2-beta-2
旧于1.2
。
带有不同限定符的相同版本,将会用基础的字符串比较,例如:1.2-beta-2
新于1.2-alpha-6
。
如果你在项目版本管理方案中没有遵循Maven的版本标准,那么对于版本比较,Maven将整个版本解释为一个简单的字符串。Maven及其核心插件将版本比较用于多项任务,最重要的是用于发布过程。
如果您使用非标准的版本管理方案,Maven发布和版本插件目标可能不会产生预期的结果。因为基本的字符串比较是在非标准的版本上进行的,所以在某些情况下,版本比较会错误地计算版本的顺序。
例如,Maven按以下顺序排列版本列表:
- 1.0.1.0
- 1.0.10.1
- 1.0.10.2
- 1.0.9.3
版本1.0.9.3
应该在1.0.10.1
和1.0.10.2
之前,但意外的第四个字段(.3
)迫使Maven将版本评估为一个字符串。
在Maven版本插件中可以看到这种对Maven影响的例子。Maven版本插件提供了以不同方式检查项目依赖关系的目标。其中一个有用的目标是versions:dependency-updates-report
,它将检查项目的依赖层次,并报告哪些项目有较新的版本。当你在协调一个大型发布时,这个目标可以帮你找到依赖配置中的陈旧引用。如果Maven错误地识别了一个较新的版本,那么在插件中也会出现错误的报告。在前面的这个例子中,若你当前版本是1.0.10.2
,那么这个插件将会将1.0.9.3
报告成一个较新的版本。
如果你打算在你的依赖关系引用中使用版本范围,版本解析也是非常重要的。参见第3节,了解关于版本变化的信息。
2 SNAPSHOT限定符
Maven对待SNAPSHOT限定符的处理方式跟其他所有限定符不同。若一个版本号以-SNAPSHOT
结尾,那么Maven会认为它是相关MajorVersion、MinorVersion或IncrementalVersion的 “尚未发布 “版本。
在一个持续集成环境中,SNAPSHOT版本在包成集成构建的最新性方面起着至关重要的作用,同时尽量减少每个集成步骤所需的重建量。
SNAPSHOP版本引用使依赖项目构建时能够获取SNAPSHOT依赖的最新部署实例。请注意,SNAPSHOT是不断变化的。每当代理部署工件时,它就会在共享仓库中更新。SHAPSHOT依赖被重新获取,在开发者的机器上,或者它在每个构建中被更新。这确保了依赖的更新和集成最新的变化,而不需要改项目中的依赖引用配置。
试想,在开发过程中若不使用SNAPSHOT,则每次发布都需要在工件、使用工件方,至少两个工程中修改版本号,麻了😵💫
通常,只有最近部署的SNAPSHOT,对于一个特定版本的工件在工件仓库中被保存。虽然仓库可以被配置为维护一个滚动归档,其中有一些特定工件的最新部署,但旧的实例通常只用于故障排除,在集成中不发挥任何作用。
持续构建服务器包括定义和执行基于Maven项目的作业的能力,如Hudson/Jenkins,可以配置为识别SNAPSHOT工件的更新,然后重建对更新工件有依赖性的项目。
3 版本范围引用
Maven能指定可接受的版本范围作为依赖,下标显示了一系列的版本规格。
范围 | 含义 |
---|---|
(,1.0] | x <= 1.0 |
1.0 | 如果1.0不可用,它通常意味着1.0或更高版本。不同的Maven插件可能对此有不同的解释,因此使用其他更具体的选项更为安全。 |
[1.0] | 正是1.0 |
[1.2,1.3] | 1.2 <= x <= 1.3 |
[1.0,2.0) | 1.0 <= x < 2.0 |
[1.5,) | x >= 1.5 |
(,1.0],[1.2,) | x <= 1.0 or x >= 1.2。多个集合用逗号隔开。 |
(,1.1),(1.1,) | 如果已知1.1不能与库结合使用,这就排除了1.1 |
当Maven遇到多个匹配的版本号时,它会使用最高匹配的版本。一般来说,版本引用应该根据需要来确定,这样Maven就可以酌情选择新的依赖版本,但也知道何时必须使用某个特定的版本。这试Maven能在跨依赖图的不同点桑指定不同版本的依赖时,选择最合适的版本。当发生这样的冲突时,Maven会从所有引用中选择最高版本。
鉴于可以选择使用版本范围,你可能会想,使用SNAPSHOT版本是否还有用。尽管你可以通过使用版本范围表达式达到一些相同的结果,但在持续构建系统中,SNAPSHOT的效果更好,原因如下:
- Maven工件仓库管理器处理SNAPSHOT比处理下一版本范围更有效。因为一个工件在一天内可以部署多次,所以存储库维护的独特实例的数量会迅速增加。
- 非SNAPSHOT发布版本是为了无限期地维护。如果你不断地发布新的版本并增加构建号或版本,存储需求很快就会变得无法管理。存储仓库管理器被设计为抛弃旧的SNAPSHOT,为新的实例腾出空间,因此所需的存储量保持不变。
- SNAPSHOT也能被Maven和Maven的发布流程识别,这让你在进行发布构建时获得了一些好处。