The version of each dependency added to the classpath should the highest version in the dependency tree. Upper version alignment ensures that upgrading packages to compatible higher versions doesn’t introduce new linkage conflicts.
Upper version alignment increases the likelihood that build systems select the right versions of direct and transitive dependencies, reducing the number of conflicts.
See the details specific to each build system in the following sections.
Use the requireUpperBoundDeps
Maven enforcer
rule
to ensure that you are using the
highest version of each dependency in your dependency tree.
For any transitive dependency that fails the requireUpperBoundDeps
check, add
the dependency as a direct dependency so that the path to the correct version
is shorter, leading Maven to select it instead of the wrong version.
To ensure that dependencies between modules in the project are consistent,
the project should publish a BOM and
the parent POM should import this BOM in its <dependencyManagement>
section.
Each module’s POM should inherit from the parent POM of the library.
To ensure consistency of dependencies from outside the project:
If the dependency publishes a BOM, import that BOM in the <dependencyManagement>
section.
If multiple imported BOMs manage the same dependency, use the
<dependencyManagement>
of the parent POM to select a compatible version,
typically the highest.
Order doesn’t matter for the override, because all explicit version
declarations in <dependencyManagement>
take precedence over all BOM
imports. Order between BOMs does matter. The first import of a dependency
takes precedence over later imports of the same dependency.
If a dependency does not have have a BOM (for example, Joda-Time), make sure only one pom.xml defines the version, so that the library doesn’t accidentally depend on different versions in different modules.
The first option is to specify the version of the dependency in the
<dependencyManagement>
section of the parent POM.
When declaring a dependency anywhere in the project, omit the version
number so that the version from the parent’s <dependencyManagement>
section takes effect.
The second option is to define a version property such as
jodatime.version
in the parent POM. Then use this property
to specify versions everywhere the dependency is imported.
Declare variables defining dependency versions in a shared ext
section in
the root build.gradle
file, and use those variables in any place declaring a
dependency.