Search code examples
javagradlekotlingradle-kotlin-dsl

How to define common dependencies in Gradle kotlin dsl from the parent project?


I am setting up a multi module Gradle build with the Kotlin DSL. Below is the top level build.gradle.kts file I am using.

subprojects {
    repositories {
        mavenCentral()
    }

    group = "com.example"
    version = "1.0.0"

    plugins.withType<JavaPlugin> {
        extensions.configure<JavaPluginExtension> {
            sourceCompatibility = JavaVersion.VERSION_11
            targetCompatibility = JavaVersion.VERSION_11

            dependencies {
                implementation(platform("org.springframework.boot:spring-boot-dependencies:2.2.2.RELEASE"))
            }

            tasks.withType<Test> {
                useJUnitPlatform()
            }
        }
    }
}

I get the following error

* What went wrong:
Script compilation error:

  Line 15:                 implementation(platform("org.springframework.boot:spring-boot-dependencies:2.2.2.RELEASE"))
                           ^ Unresolved reference: implementation

1 error

Question

  • How do I set common dependencies from the root build.gradle.kts?

Solution

  • I would advise you to read the Gradle Kotlin DSL Primer. The section "Understanding when type-safe model accessors are available" explains why you shouldn't expect implementation to be defined at this place (emphasis mine):

    The set of type-safe model accessors available is calculated right before evaluating the script body, immediately after the plugins {} block. Any model elements contributed after that point do not work with type-safe model accessors. For example, this includes any configurations you might define in your own build script.

    So you cannot use a typesafe accessor for implementation in the top-level build.gradle, except if you would apply the java plugin in its plugins {} block (which is not advised, unless the root project itself contains sources).

    Instead, use unsafe accessors, as demonstrated in the section Understanding what to do when type-safe model accessors are not available, like this:

    plugins.withType<JavaPlugin> {
            extensions.configure<JavaPluginExtension> {
                sourceCompatibility = JavaVersion.VERSION_11
                targetCompatibility = JavaVersion.VERSION_11
    
                dependencies {
                    "implementation"(platform("org.springframework.boot:spring-boot-dependencies:2.2.2.RELEASE"))
                }
    
                tasks.withType<Test> {
                    useJUnitPlatform()
                }
            }
        }