Despite what the documentation says, it appears that a is a synonym for alpha only when it is immediately followed by a digit. So
2.0.0-a1 is equivalent to 2.0.0-alpha1 and 2.0.0-alpha-1 (but not 2.0.0-alpha.1)
- the
a in 2.0.0-a, 2.0.0-a.1 or 2.0.0-a-1 is an "unknown qualifier", not equivalent to 2.0.0-alpha-1, and sorted after all the known qualifiers
The behaviour appears because ComparableVersion has two ways of defining aliases, in the inner class that deals with string components:
private static final List<String> QUALIFIERS =
Arrays.asList( "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" );
private static final Properties ALIASES = new Properties();
static
{
ALIASES.put( "ga", "" );
ALIASES.put( "final", "" );
ALIASES.put( "release", "" );
ALIASES.put( "cr", "rc" );
}
// ...
StringItem( String value, boolean followedByDigit )
{
if ( followedByDigit && value.length() == 1 )
{
// a1 = alpha-1, b1 = beta-1, m1 = milestone-1
switch ( value.charAt( 0 ) )
{
case 'a':
value = "alpha";
break;
case 'b':
value = "beta";
break;
case 'm':
value = "milestone";
break;
default:
}
}
this.value = ALIASES.getProperty( value , value );
}
- A special-case scenario for single-letter qualifiers
a, b, and m, that is only triggered if followedByDigit==true, and that only happens when the qualifier was terminated by the next character being a digit.
- A list of aliases:
ga, final and release are exactly equivalent to the empty string (with the latter being the canonical form), and cr's canonical form is rc. This part behaves as the OP expects.
I would guess that this is based on observed version usage, where sometimes letters are used literally as versions (e.g. OpenSSL used to use a trailing letter or two to number patch releases, such as 0.9.7m or 0.9.8zh), while alpha, beta and milestone releases always have a release number in practice, and projects using a short version aren't going to put any extra characters in: so a by itself meaning "alpha" never actually occurs.
It's a shame it's not documented properly!