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 {
...
}
...
}