Search code examples
gradlespring-bootdependency-managementspring-boot-gradle-plugin

Gradle dependency plugin in a multi module Spring Boot project


What does a correct Gradle configuration look like in a multi-module project that uses the Gradle plugins spring-boot-dependencies and spring-boot?

I have the following project setup:

parent
  |
  + build.gradle
  |
  + alpha
  |   |
  |   + build.gradle
  |
  + beta
  |   |
  |   + build.gradle
  • The parent module contains common project configuration.
  • The alpha module is a module in which I would like to import dependencies using versions numbers specified in the spring-boot-dependencies bom, but the result of the is a standard jar.
  • The beta module is a module that depends on alpha and the result is an executable Spring Boot jar file (including all dependencies). Consequently, this project needs both the spring-boot-dependencies as well as the spring-boot plugin.

In order to keep the Gradle files DRY, I have extracted common module scripts to the parent's build.gradle file.

Attempts to execute $ gradle build using the project configuration below results in:

> Plugin with id 'io.spring.dependency-management' not found.

parent gradle.build

allprojects {
    group = "com.example"
    version '0.0.1-SNAPSHOT'

    ext {
        dependencyManagementPluginVersion = '0.5.3.RELEASE'
        springBootVersion = '1.3.0.RC1'
    }

    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'idea'
}

subprojects {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    buildscript {
        repositories {
            jcenter()
            maven { url "https://repo.spring.io/snapshot" }
            maven { url "https://repo.spring.io/milestone" }
        }
        dependencies {
            classpath("io.spring.gradle:dependency-management-plugin:${dependencyManagementPluginVersion}")
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
    }

    apply plugin: 'io.spring.dependency-management'

    dependencyManagement {
        imports {
            mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
//            mavenBom("org.springframework.boot:spring-boot-starter-parent:${springBootVersion}")
        }
    }
}

alpha build.gradle

dependencies {
    compile('org.springframework:spring-web')
}

beta gradle.build

apply plugin: 'spring-boot'

dependencies {
    compile project(':alpha')
    compile('org.springframework.boot:spring-boot-starter')
    compile('org.springframework.boot:spring-boot-starter-web')
}

Comments:

  • The behavior of the spring-boot plugin was changed in Spring Boot 1.3.0.M1
  • Gradle version: 2.8
  • Spring Boot version 1.3.0.RC1

Solution

  • It turns out that parent/build.gradle should be rearranged in the following way:

    buildscript {
        ext {
            dependencyManagementPluginVersion = '0.5.3.RELEASE'
            springBootVersion = '1.3.0.RC1'
        }
        repositories {
            jcenter()
            maven { url "https://repo.spring.io/snapshot" }
            maven { url "https://repo.spring.io/milestone" }
        }
        dependencies {
            classpath("io.spring.gradle:dependency-management-plugin:${dependencyManagementPluginVersion}")
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
    }
    
    allprojects {
        group = "com.example"
        version '0.0.1-SNAPSHOT'
    
        apply plugin: 'java'
        apply plugin: 'eclipse'
        apply plugin: 'idea'
    }
    
    subprojects {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    
        apply plugin: 'io.spring.dependency-management'
    
        dependencyManagement {
            imports {
                mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
    //          mavenBom("org.springframework.boot:spring-boot-starter-parent:${springBootVersion}")
            }
        }
    }
    

    The problem lies in the fact that buildscript block for subprojects was indeed configured well but... in a wrong place. This subprojects block relates to subprojects but it will be evaluated in the script it was declared, and there were no dependencies declared for the plugin it was trying to apply.