Version Numbers


Version numbers in install4j should be a sequence of version components separated by dots:

A.B.C...

where A, B, C are composed of alphanumeric characters without dots, for example 1, 112, 5-rc-9 or release.

Version comparisons in the auto-update API

The auto-update API in the com.install4j.api.update package has to determine whether a new version is greater than an installed version or not. Usually, the getPossibleUpdateEntry() method of the update descriptor is called to make that comparison:

UpdateDescriptor updateDescriptor = ...;
if (updateDescriptor.getPossibleUpdateEntry() != null) {
    //TODO an update is available
}

In its implementation, it calls

UpdateDescriptorEntry updateDescriptorEntry = ...;
String installedVersion = context.getVersion();
if (updateDescriptorEntry.checkVersionCompatible(installedVersion)) {
  // TODO This entry has a version that is newer than the installed version
}

The checkVersionCompatible method checks if the supplied version

Internally, it calls

if (UpdateChecker.isVersionGreaterThan(newVersion, installedVersion)) {
    // TODO newVersion is indeed greater than installedVersion
}

to compare the version strings of the installed version with the new version in the update descriptor entry.

Comparison algorithm for versions

Let us call the two versions that should be compared A and B. A has NA components while B has NB components. Components are determined by splitting the version string with a java.util.StringTokenizer and a single dot as a delimiter. The components are denoted as A(0) ... A(NA-1) and B(0) ... B(NB-1).

The following rules apply when comparing these two versions:

  1. Before the comparison, the following replacements are performed for both versions in this order:
    • When going from left to right, a boundary between digits and non-digits creates a new component, for example 2.3a becomes 2.3.a. Boundaries between non-digits and digits are left intact, for example 2.3.a4. This means that non-numeric characters only appear as leading characters for each component.
    • After dots, any "-" and "_" characters are discarded.
    • All characters are converted to lower-case, for example 1.0-HEAD becomes 1.0.head.
  2. The version that has less components is filled up with components of value 0, so that both versions have the same number of components N = max(NA, NB).
  3. The versions are compared from left to right, component by component. The version comparison is finished for the first K = 0 ... N-1 for which the components are not equal:
    B(K) > A(K) => B > A
    B(K) < A(K) => B < A
  4. Components that have leading non-numeric characters are considered as less than components with leading numeric characters. For example 2.3-pre < 2.3, because 2.3-pre is converted to 2.3.pre and 2.3 is converted to 2.3.0.
  5. If both components have a non-numeric part, version comparison is decided by their lexicographic comparison, as performed by String.compareTo(...). For example, 2.Z3 > 2.X4. If the non-numeric parts are equal, the numeric parts are compared where missing numeric parts are set to 0.
  6. Otherwise the components are both numeric and can be compared numerically.

Some examples from the unit test for the version comparison method are:

1 < 2
1.1 < 2
1.1 < 1.2
1.1.0 < 1.1.1
9.0 < 10
1.6.0_4 < 1.6.0_22
1.6.0 < 1.6.0_22
1.6.0_4 < 1.6.1
1.0beta1 < 1.0beta2
1.0.beta1 < 1.0.beta2
A10 < A11
2.0 beta 1 < 2.0
2.0 beta 1 < 2.0.0
2.0 beta 1 < 2.0 beta 2
1.0rc1 < 1.0
1.0-rc1 < 1.0
1.0.rc1 < 1.0
1.0alpha < 1.0rc1
1.0alpha < 1.0alpha1
1.0alpha9 < 1.0alpha10
1.0alpha100 < 1.0.rc100
1.0.alpha < 1.0-rc
z < 1
DEVELOP-HEAD130714193704 < DEVELOP-HEAD130714193705