Is there a way to get Gradle to behave a bit more ...
# community-support
c
Is there a way to get Gradle to behave a bit more like the spring boot dependency-management plugin when using platform boms? Currently in spring dependency management, if you're using a bom with lib1:version1, and you add a dependency that tries to bump lib1 to version2, it will prefer version1. In Gradle, it'll completely ignore the version in the platform("bom") and let version2 upgrade.
t
enforcedPlatform()
, but DO NOT publish any project using it as enforcement is transitive. https://docs.gradle.org/current/userguide/platforms.html#sec:enforced-platform
c
Does enforcedPlatform let a downstream project purposefully override a particular version, in the case where you might need spot fixes?
In a test project for example, if I do something like
Copy code
implementation(enforcedPlatform("org.springframework.boot:spring-boot-dependencies:2.7.18"))
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-logging")
    implementation("io.github.microutils:kotlin-logging:3.0.5")
    // i.e. fixes a bug that's not in the platform, or forcefully downgrades a dependency
    implementation("org.slf4j:slf4j-api:2.0.12!!")
then gradle fails with
Copy code
Execution failed for task ':app:compileJava'.
> Could not resolve all files for configuration ':app:compileClasspath'.
   > Could not resolve org.slf4j:slf4j-api:{strictly 2.0.12}.
     Required by:
         project :app
      > Cannot find a version of 'org.slf4j:slf4j-api' that satisfies the version constraints:
           Dependency path 'gradle-enforced-platform-testing:app:unspecified' --> 'org.slf4j:slf4j-api:{strictly 2.0.12}'
           Constraint path 'gradle-enforced-platform-testing:app:unspecified' --> 'org.springframework.boot:spring-boot-dependencies:2.7.18' (enforced-platform-compile) --> 'org.slf4j:slf4j-api:1.7.36'
           Dependency path 'gradle-enforced-platform-testing:app:unspecified' --> 'io.github.microutils:kotlin-logging:3.0.5' (jvmApiElements-published) --> 'io.github.microutils:kotlin-logging-jvm:3.0.5' (jvmApiElements-published) --> 'org.slf4j:slf4j-api:2.0.3'
           Dependency path 'gradle-enforced-platform-testing:app:unspecified' --> 'org.springframework.boot:spring-boot-starter-logging:2.7.18' (apiElements) --> 'ch.qos.logback:logback-classic:1.2.12' (compile) --> 'org.slf4j:slf4j-api:1.7.32'
           Dependency path 'gradle-enforced-platform-testing:app:unspecified' --> 'org.springframework.boot:spring-boot-starter-logging:2.7.18' (apiElements) --> 'org.apache.logging.log4j:log4j-to-slf4j:2.17.2' (compile) --> 'org.slf4j:slf4j-api:1.7.35'
           Dependency path 'gradle-enforced-platform-testing:app:unspecified' --> 'org.springframework.boot:spring-boot-starter-logging:2.7.18' (apiElements) --> 'org.slf4j:jul-to-slf4j:1.7.36' (compile) --> 'org.slf4j:slf4j-api:1.7.36'
t
The doc talks about
exclude
, but I have never used enforcedPlatform myself so really can't help further, sorry
c
Ok found this
Copy code
implementation(enforcedPlatform("org.springframework.boot:spring-boot-dependencies:2.7.18")) {
        (this as ExternalModuleDependency).exclude("org.slf4j", "slf4j-api")
    }
That's awful but closer to what I was thinking.
v
It's awful because you should not use enforced platforms except for rare edge cases. It would be much better if you try to free yourself mentally from the broken Maven logic that plugin was porting over to the Gradle world and instead use what makes more sense, that is using
platform
as also the Spring Boot documentation recommends. If you "add a dependency that tries to bump lib1 to version2", that means this dependency declares that it needs version 2. Only giving it version 1 is playing Jeopardy, as it clearly told you it needs version 2.
👍 1
☝️ 2