gradledependency-managementgradle-dependenciesmaven-bom

Which Maven BOM determines a dependency's version in Gradle 5?


I am currently developing a Gradle 5 project that imports two different Maven BOMs. Therefore, I use the native Gradle syntax without the dependency management plugin. However, both BOMs may define different versions for the same dependency.

dependencies {
    implementation platform ("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")
    implementation platform ("com.organisation:xyz:${otherBomVersion}")
}

As far as I know in Maven the first BOM which defines a version for a given dependency determines it. In contrast, in the Gradle dependency management plugin the last BOM which defines a version for a given dependency determines it.

How is the order of imported BOMs handled in pure Gradle 5?


Solution

  • The order of BOMs, or wherever the dependency is declared, doesn't matter at all in Gradle. Unlike Maven, which uses a nearest first approach, Gradle takes all dependency information in consideration and selects the highest. The documentation states

    Gradle will consider all requested versions, wherever they appear in the dependency graph. Out of these versions, it will select the highest one.

    A practical example. The following declaration will always select 2.2.5.RELEASE of Spring Cloud Gateway defined by spring-cloud-dependencies BOM version Hoxton.SR8 no matter which platform() declaration is listed first:

    dependencies {
        implementation platform('org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8')
        implementation platform('org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR6')
        
        implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    }
    

    The dependency insight report may look like this:

    > gradlew -q dependencyInsight --dependency spring-cloud-starter-gateway
    org.springframework.cloud:spring-cloud-starter-gateway:2.2.5.RELEASE (by constraint)
       variant "compile" [
          org.gradle.status              = release (not requested)
          org.gradle.usage               = java-api
          org.gradle.libraryelements     = jar (compatible with: classes)
          org.gradle.category            = library (not requested)
    
          Requested attributes not found in the selected variant:
             org.gradle.dependency.bundling = external
             org.gradle.jvm.version         = 8
       ]
    
    org.springframework.cloud:spring-cloud-starter-gateway:2.2.5.RELEASE
    \--- org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8
         \--- compileClasspath
    
    org.springframework.cloud:spring-cloud-starter-gateway -> 2.2.5.RELEASE
    \--- compileClasspath
    

    You may use enforcedPlatform() should you prefer versions from a specific BOM.