Home > Back-end >  Use main Gradle project to define all dependencies versions
Use main Gradle project to define all dependencies versions

Time:03-07

I want to create one main Gradle project which hosts all project dependencies:

Main Gradle project:

plugins {
    id 'org.springframework.boot' version '2.6.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'maven-publish'
}

group = 'com.parent.dependencies'
version = '0.0.1'
sourceCompatibility = '11'

ext {
    set('springCloudVersion', "2021.0.1")
    artifactory_contextUrl = "http://192.168.1.112/repository"
}

repositories {
    mavenCentral()
    maven {
        url "${artifactory_contextUrl}/plugins-release"
        allowInsecureProtocol = true
    }
}

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.threeten:threetenbp:1.5.1'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    // Lombok
    compileOnly 'org.projectlombok:lombok:1.18.22'
    annotationProcessor 'org.projectlombok:lombok:1.18.22'
    testCompileOnly 'org.projectlombok:lombok:1.18.22'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
    // Swagger
    implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
    implementation 'org.springframework.boot:spring-boot-starter-hateoas:2.6.3'
    implementation group: 'com.netflix.hystrix', name: 'hystrix-core', version: '1.5.18'
    implementation group: 'org.springframework.security', name: 'spring-security-core', version: '5.6.1'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
    resolutionStrategy {
        cacheDynamicVersionsFor 0, "seconds"
        cacheChangingModulesFor 0, "seconds"
    }
}

bootJar {
    enabled = false
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
    repositories {
        mavenLocal()
    }
}

test {
    useJUnitPlatform()
}

Sub project which will read all dependencies versions from parent Gradle project:

plugins {
    id 'org.springframework.boot' version '2.6.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id 'maven-publish'
}

group = 'com.child'
version = '0.0.1'
sourceCompatibility = '11'

ext {
    artifactory_contextUrl = "http://192.168.1.112/repository"
}

repositories {
    mavenCentral()
    maven {
        url "${artifactory_contextUrl}/plugins-release"
        allowInsecureProtocol = true
    }
}

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.threeten:threetenbp'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    // Lombok
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    // Swagger
    implementation 'io.springfox:springfox-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-hateoas'
    implementation 'com.netflix.hystrix:hystrix-core'
    implementation 'org.springframework.security:spring-security-core'
    testImplementation 'org.junit.jupiter:junit-jupiter-api'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

dependencyManagement {
    imports {
        mavenBom "com.parent:com-parent-dependencies:0.0.1"
    }
}

bootJar {
    enabled = false
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
    repositories {
        mavenLocal()
    }
}

test {
    useJUnitPlatform()
}

When I try to compile the child project I get error:

Execution failed for task ':compileJava'.
> Could not resolve all files for configuration ':compileClasspath'.
   > Could not find org.threeten:threetenbp:.
     Required by:
         project :
   > Could not find io.springfox:springfox-boot-starter:.
     Required by:
         project :
   > Could not find com.netflix.hystrix:hystrix-core:.
     Required by:
         project :

Do you know how I can define properly the parent Gradle project with all dependencies versions and use the child project without defining dependencies versions?

CodePudding user response:

There’s a relatively new Gradle feature called “version catalogs”. With those you can centrally declare dependencies that you’d like to share between multiple projects of your build (or even between different builds).

In your concrete example, you’d add something like the following to your settings.gradle file:

dependencyResolutionManagement {
    versionCatalogs {
        libs {
            library('spring-cloud-bom', 'org.springframework.cloud:spring-cloud-dependencies:2021.0.1')
            library('spring-cloud-starter', 'org.springframework.cloud', 'spring-cloud-starter-netflix-eureka-client').withoutVersion()
            library('spring-boot-starter-validation', 'org.springframework.boot', 'spring-boot-starter-validation').withoutVersion()
            library('spring-boot-starter-test', 'org.springframework.boot', 'spring-boot-starter-test').withoutVersion()
            library('threetenbp', 'org.threeten:threetenbp:1.5.1')
            library('spring-boot-starter-actuator', 'org.springframework.boot', 'spring-boot-starter-actuator').withoutVersion()
            library('lombok', 'org.projectlombok:lombok:1.18.22')
            library('springfox-boot-starter', 'io.springfox:springfox-boot-starter:3.0.0')
            library('spring-boot-starter-hateoas', 'org.springframework.boot:spring-boot-starter-hateoas:2.6.3')
            library('hysterix-core', 'com.netflix.hystrix:hystrix-core:1.5.18')
            library('spring-security-core', 'org.springframework.security:spring-security-core:5.6.1')
            library('junit-jupiter-api', 'org.junit.jupiter:junit-jupiter-api:5.8.2')
            library('junit-jupiter-engine', 'org.junit.jupiter:junit-jupiter-engine:5.8.2')
        }
    }
}

Then, in both build.gradle files, you’d replace your dependencies blocks with the following:

dependencies {
    implementation libs.spring.cloud.starter
    implementation libs.spring.boot.starter.validation
    testImplementation libs.spring.boot.starter.test
    implementation libs.threetenbp
    implementation libs.spring.boot.starter.actuator
    // Lombok
    compileOnly libs.lombok
    annotationProcessor libs.lombok
    testCompileOnly libs.lombok
    testAnnotationProcessor libs.lombok
    // Swagger
    implementation libs.springfox.boot.starter
    implementation libs.spring.boot.starter.hateoas
    implementation libs.hysterix.core
    implementation libs.spring.security.core
    testImplementation libs.junit.jupiter.api
    testRuntimeOnly libs.junit.jupiter.engine
}

As you’re using a Maven BOM for Spring, you’ll also have to use the following updated dependencyManagement block in all projects:

dependencyManagement {
    imports {
        mavenBom libs.spring.cloud.bom.get().toString()
    }
    resolutionStrategy {
        cacheDynamicVersionsFor 0, "seconds"
        cacheChangingModulesFor 0, "seconds"
    }
}

That should be it. I could successfully test your sample build configurations with my updates at least on Gradle 7.4.

CodePudding user response:

If your main project has code requiring these dependencies, use allprojects

allprojects {
    repositories {
        ...
    }

    dependencies {
        ...
    }
    ...
}

If your main project does not has any code requiring these dependencies, use subprojects

subprojects {
    repositories {
        ...
    }

    dependencies {
        ...
    }
    ...
}
  • Related