Home > Blockchain >  How do I exclude a dependency from being pinned by Spring Boot's dependency management plugin?
How do I exclude a dependency from being pinned by Spring Boot's dependency management plugin?

Time:11-19

I am using Spring Boot and the Gradle dependency management plugin:

plugins {
    id 'org.springframework.boot' version '2.5.6'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

What happens is that this uses the Spring Boot dependency BOM to resolve any dependency versions. I'm running into issues because some libraries that I'm using require different versions of these dependencies and when the plugin overrides these then I run into compatibility issues. For example, I'm using Debezium 1.7.1 which requires Kafka 2.8.1 but Spring still insists on downgrading that to 2.7.1, or the version that is pinned in the above BOM file.

I have two options here as far as I can tell:

  1. Somehow exclude the Spring dependency management plugin from trying to resolve the version for this dependency (Kafka) and let Debezium do it
  2. Manually override the Spring property for the dependency version:
ext['kafka.version'] = '2.8.1'

The latter works but requires me to version Kafka separately from Debezium, which will be prone to breaking.

How do I achieve the former, or are there any cleaner alternatives? Thank you!

CodePudding user response:

A cleaner and more efficient approach would be to use Gradle's platform support. So, drop/remove the Spring Dependency Management plugin entirely:

import org.springframework.boot.gradle.plugin.SpringBootPlugin;

dependencies {
    implementation(platform(SpringBootPlugin.BOM_COORDINATES))
}

Debezium also offers a BOM which you can also import as well:

import org.springframework.boot.gradle.plugin.SpringBootPlugin;

dependencies {
    implementation(platform(SpringBootPlugin.BOM_COORDINATES))
    implementation(platform("io.debezium:debezium-bom:1.7.1.Final"))
}

With these changes in place, Gradle's standard dependency resolution will be in play. By default, the higher version of two dependencies will win. Spring Boot 2.5.6 has Kafka at 2.7.1 while Debezium defines a higher version, so naturally Debezium's version will win.

If for some reason you need to control a specific dependency version, then you can do:

import org.springframework.boot.gradle.plugin.SpringBootPlugin;

configurations.configureEach {
    resolutionStrategy.eachDependency {
        if (requested.group == "org.apache.kafka") {
            useVersion("x.x.x")
            because("We require this version for X reason")
        }
    }
}

dependencies {
    implementation(platform(SpringBootPlugin.BOM_COORDINATES))
    implementation(platform("io.debezium:debezium-bom:1.7.1.Final"))
}

The above is more more expressive and efficient. I stress efficient because the Spring Dependency Management plugin is greedy, meaning it "touches" everything when it does not need to. I recommend watching this presentation by Jenn Strater and Andy Wilkinson on the differences.

  • Related