Weird "Kotlin Gradle plugin was loaded multiple times" in simplest setup with modular Gradle build logic

391 views Asked by At

Using the latest stable Kotlin 1.9.20 and Gradle 8.4 running on JDK 17

Consider the following project structure:

├── build-logic
│   ├── kotlin-project
│   │   ├── build.gradle.kts
│   │   └── src
│   │       └── main
│   │           └── kotlin
│   │               └── kotlin-convention.gradle.kts
│   ├── other
│   │   ├── build.gradle.kts
│   │   └── src
│   │       └── main
│   │           └── kotlin
│   │               └── other-convention.gradle.kts
│   └── settings.gradle.kts
├── lib1
│   └── build.gradle.kts
├── lib2
│   └── build.gradle.kts
└── settings.gradle.kts

The main project contains 2 components lib1 and lib2 and uses build logic from ./build-logic:

pluginManagement {
    includeBuild("build-logic")
}

rootProject.name = "kotlin-plugin-loaded-multiple-times-example"

include("lib1")
include("lib2")

Here is the build.gradle.kts for lib1:

plugins {
    id("kotlin-convention")
}

and lib2:

plugins {
    id("kotlin-convention")
    id("other-convention") // <-- it is the only difference between 'lib1' and 'lib2' setup
}

Now, as you can see there are 2 components in build logic: "Kotlin convention" and "some other convention". That's the only content of the build-logic/settings.gradle.kts:

include("kotlin-project")
include("other")

The build-logic/kotlin-project/build.gradle.kts is:

plugins {
    `kotlin-dsl`
}

repositories {
    gradlePluginPortal()
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
}

and the kotlin-convention.gradle.kts is:

plugins {
    kotlin("jvm") // <-- simply Kotlin plugin applied, nothing more
}

repositories {
    mavenCentral()
}

The last bit in this build is the "some other convention". build-logic/other/build.gradle.kts:

plugins {
    `kotlin-dsl`
}

repositories {
    gradlePluginPortal()
}

and, finally, other-convention.gradle.kts is just an empty file for simplicity (but you can add jacoco or some other side plugin, it does not matter).

Now, if you run gradle build you will get a warning message:

The Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build.
This might happen in subprojects that apply the Kotlin plugins with the Gradle 'plugins { ... }' DSL if they specify explicit versions, even if the versions are equal.
Please add the Kotlin plugin to the common parent project or the root project, then remove the versions in the subprojects.
If the parent project does not need the plugin, add 'apply false' to the plugin line.
See: https://docs.gradle.org/current/userguide/plugins.html#sec:subprojects_plugins_dsl
The Kotlin plugin was loaded in the following projects: ':lib1', ':lib2'

As soon as you remove id("other-convention") from lib2/build.gradle.kts or move other-convention.gradle.kts to kotlin-project build-logic component, the warning disappears.

What is wrong with this setup?

0

There are 0 answers