Skip to content

Latest commit

 

History

History
68 lines (50 loc) · 2.99 KB

File metadata and controls

68 lines (50 loc) · 2.99 KB
jlbp
id
JLBP-16
permalink /JLBP-16

Ensure upper version alignment of dependencies for consumers

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.

Achieving upper version alignment

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.

Maven

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.

Gradle

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.