distributionUrl=https://services.gradle.org/distributions/gradle-5.2.1-all.zip
Acme Lib One BOM .jar depends on Acme Lib Two BOM .jar.
Acme Lib One
dependencies {
api ('com.acme.spring:reactive-couchbase-spring-boot-starter:unspecified') {
}
Acme Lib Two (a.ka. “com.acme.spring:reactive-couchbase-spring-boot-starter”)
plugins {
id 'java'
id 'jacoco'
id "com.jfrog.artifactory" version "4.9.7"
id 'org.springframework.boot' version "2.1.9.RELEASE" apply false
id 'maven-publish'
}
apply plugin: 'maven-publish'
apply plugin: 'java'
apply plugin: "java-library"
apply plugin: 'jacoco'
apply plugin: 'io.spring.dependency-management'
dependencies {
implementation'org.springframework.boot:spring-boot-starter'
api ('org.springframework.boot:spring-boot-starter-data-couchbase-reactive'){
}
api ("com.couchbase.client:java-client") {
version {
strictly '2.7.11'
}
}
}
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
}
}
Objective: I want “Acme Lib Two” to specify newer version of couchbase java client so that no consumer of Lib One or Lib One itself needs to override the version.
What happens instead: 2.7.9 is seen by “Acme Lib Two” and consumer projects of “Acme Lib Two”
Yes, I am totally aware how Spring devs intended to override version:
ext[‘couchbase-client.version’] = ‘2.7.11’ - the problem with that is that you can only apply this at consumer level, i.e. project consuming libraries. If you specify it at library level “Acme Project One” the library self sees 2.7.11 but not the consumer project of the library. Consumer project will see 2.7.9. Unless consumer project self specifies “ext”.
IMO this is against expectations. Either “ext” or “strictly” specified by the lib should tell downstream consumers what to use? I don’t want to go to every project using the lib and put this ext, this is silly.
Analysis from Acme Lib One:
./gradlew -q dependencyInsight --dependency java-client
com.couchbase.client:java-client:2.7.9 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.component.category = library (not requested)
]
com.couchbase.client:java-client:2.6.2 -> 2.7.9
\--- org.springframework.data:spring-data-couchbase:3.1.11.RELEASE
\--- org.springframework.boot:spring-boot-starter-data-couchbase-reactive:2.1.9.RELEASE
\--- com.acme.spring:reactive-couchbase-spring-boot-starter:unspecified
\--- compileClasspath
com.couchbase.client:java-client:2.7.11 -> 2.7.9
\--- com.acme.spring:reactive-couchbase-spring-boot-starter:unspecified
\--- compileClasspath
2.7.9 is presumably coming from here,
https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.1.9.RELEASE/spring-boot-dependencies-2.1.9.RELEASE.pom
so why doesn’t this back away when a lib told explicitly what to use… I tried “force true” , “constraints” (failed mavenLocalPublish and artifactoryPublish - maybe old version, ) I tried exclusions, apart from “constraints” everything works only from consumer project explicitly. Library self is powerless to override or enforce 2.7.11 for consumers.
Conceptually, this all means that intermediary libraries cannot navigate consumers to modified upstream transitive library versions, I am trying to understand if this is expected behavior or I am doing something wrong.