How does maven sort version numbers?
maven, maven-3
Solution
Since version 3.0, Maven uses a consistent system to compare version numbers for both individual versions and version ranges. The system now makes a lot of sense, once you've understood a few gotchas.
All comparisons are now done by ComparableVersion, which says:
- mixing of '`-`' (dash) and '`.`' (dot) separators,
- transition between characters and digits also constitutes a separator: `1.0alpha1` => `[1, 0, alpha, 1]`
- unlimited number of version components,
- version components in the text can be digits or strings,
- strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering. Well-known qualifiers (case insensitive) are:
- `alpha` or `a`
- `beta` or `b`
- `milestone` or `m`
- `rc` or `cr`
- `snapshot`
- (the empty string) or `ga` or `final`
- `sp`
- Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive),
- a dash usually precedes a qualifier, and is always less important than something preceded with a dot.
This means that versions come out in the following order, which I think makes perfect sense, apart from 1.0-SNAPSHOT right in the middle:
- `1.0-beta1-SNAPSHOT`
- `1.0-beta1`
- `1.0-beta2-SNAPSHOT`
- `1.0-rc1-SNAPSHOT`
- `1.0-rc1`
- `1.0-SNAPSHOT`
- `1.0`
- `1.0-sp`
- `1.0-whatever`
- `1.0.1`
The main gotcha I found in all this is that `snapshot` comes after `beta` or `rc`, so you can't have a development version of `1.0-SNAPSHOT`, then release `1.0-beta1` or `1.0-rc1` and have Maven understand that those are later.
Also note that `1.0-beta-1` is exactly the same as `1.0beta1`, and `1.0` is exactly the same as `1` or `1.0.0`.
Version ranges now work (nearly) the way you'd expect, too. For example, `[1.0-alpha-SNAPSHOT,1.0]` will find `1.0-beta1-SNAPSHOT`, `1.0-beta1`, `1.0-rc1-SNAPSHOT`, `1.0-rc1`, `1.0-SNAPSHOT` or `1.0`, preferring later items over earlier ones. This is fully supported by `mvn versions:resolve`, M2Eclipse and so on.
Problem
Maven seems to have the ability to indicate a range of versions such as `<version>[1.2.3,)</version>` how does maven figure out what is a newer or older version when there is no consistent versioning scheme that all open source packages follow. For example - junit `4.10` - slf4j `1.7.2` - Hibernate `4.1.7.Final` - Spring `3.1.2.RELEASE` How does maven figure what is an older vs. newer version of a package in maven? What if package uses letters as versions numbers something along the lines of A,B,C or A2,A2,A4 ... etc. Is there supposed to be a standard official way to version packages in maven? Are common open source packages like spring and hibernate ignoring this versioning convention?