1

I have a gradle project which is used as a library in other projects. The library project specifies a dependency:

        compile('org.apache.kafka:kafka-clients') {
            version {
                strictly '2.6.1'
            }
        }

However, when building another project which uses this library, the version gets downgraded to '2.3.1'. I found out that it happens because the project also uses Spring Boot gradle plugin and Spring Boot depends on that version. How can I ensure that the version from my custom library is used? I know how to do it directly in the child project but the problem is that there are many projects that use the library and I would like to avoid repeating dependency version in each of them. Is there a way to do it in a single place (either a custom library or a custom gradle plugin)?

I already tried specifying dependency version with strictly keyword and trying to put kafka.version in gradle.properties. However, it all works only if done directly in the child project but not if I do it in the library project.

Igor
  • 11
  • 3

1 Answers1

0

You could use ExtraPropertiesExtension ext to overwrite the default behavior: https://docs.spring.io/spring-boot/docs/2.5.3/gradle-plugin/reference/htmlsingle/#managing-dependencies.dependency-management-plugin.customizing.

Example

Suppose I have a multi-module project like this:

root
├── aa
│   └── build.gradle
├── bb
│   └── build.gradle
└── settings.gradle

The project aa contains the Kafka dependency:

// aa/build.gradle

plugins {
    id "java"
    id "java-library"
}

repositories {
    mavenCentral()
}

dependencies {
    api "org.apache.kafka:kafka-clients:2.6.1"
}

The project bb has Spring Boot and depends on aa:

// bb/build.gradle

plugins {
    id "java"
    id("org.springframework.boot") version "2.5.2"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
}

repositories {
    mavenCentral()
}

ext["kafka.version"] = '2.6.1'

dependencies {
    implementation project(":aa")

    implementation("org.springframework.boot:spring-boot-starter-web")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

Dependency Tree Without ext

productionRuntimeClasspath
+--- project :aa
|    \--- org.apache.kafka:kafka-clients:2.6.1 -> 2.7.1
|         +--- com.github.luben:zstd-jni:1.4.5-6
|         +--- org.lz4:lz4-java:1.7.1
|         +--- org.xerial.snappy:snappy-java:1.1.7.7
|         \--- org.slf4j:slf4j-api:1.7.30 -> 1.7.31
\--- org.springframework.boot:spring-boot-starter-web -> 2.5.2
     +--- org.springframework.boot:spring-boot-starter:2.5.2
     |    +--- org.springframework.boot:spring-boot:2.5.2
     .
     .

Dependency Tree With ext

productionRuntimeClasspath
+--- project :aa
|    \--- org.apache.kafka:kafka-clients:2.6.1
|         +--- com.github.luben:zstd-jni:1.4.4-7
|         +--- org.lz4:lz4-java:1.7.1
|         +--- org.xerial.snappy:snappy-java:1.1.7.3
|         \--- org.slf4j:slf4j-api:1.7.30 -> 1.7.31
\--- org.springframework.boot:spring-boot-starter-web -> 2.5.2
     +--- org.springframework.boot:spring-boot-starter:2.5.2
     |    +--- org.springframework.boot:spring-boot:2.5.2
     .
     .

If you want to apply this to all the subprojects, you could set the ext in buildSrc's plugin or the subprojects block in the root project's build.gradle.

chehsunliu
  • 1,559
  • 1
  • 12
  • 22
  • Yep but I do not have a multi-model project. I have multiple individual projects which only use the same shared custom library. I also have a custom gradle plugin which is used in all those projects. So I was wondering if I could define kafka version that I want to use in each project in either the plugin or the library. – Igor Aug 04 '21 at 13:30