Skip to content

Commit c29ad27

Browse files
committed
add more detail to the logKgpClassNotFoundWarning warning, and prevent multiple warnings
1 parent 55d23db commit c29ad27

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

dokka-runners/dokka-gradle-plugin/src/main/kotlin/adapters/KotlinAdapter.kt

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import org.gradle.kotlin.dsl.*
1919
import org.jetbrains.dokka.gradle.DokkaBasePlugin
2020
import org.jetbrains.dokka.gradle.DokkaExtension
2121
import org.jetbrains.dokka.gradle.adapters.KotlinAdapter.Companion.currentKotlinToolingVersion
22+
import org.jetbrains.dokka.gradle.adapters.KotlinAdapter.Companion.findKotlinBasePlugins
23+
import org.jetbrains.dokka.gradle.adapters.KotlinAdapter.Companion.logKgpClassNotFoundWarning
2224
import org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceSetSpec
2325
import org.jetbrains.dokka.gradle.engine.parameters.KotlinPlatform
2426
import org.jetbrains.dokka.gradle.engine.parameters.SourceSetIdSpec
@@ -39,6 +41,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataCompilation
3941
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
4042
import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion
4143
import java.io.File
44+
import java.util.Collections.newSetFromMap
45+
import java.util.concurrent.ConcurrentHashMap
4246
import javax.inject.Inject
4347

4448
/**
@@ -221,8 +225,7 @@ abstract class KotlinAdapter @Inject constructor(
221225
when (ex) {
222226
is ClassNotFoundException,
223227
is NoClassDefFoundError -> {
224-
logger.info("Dokka Gradle Plugin could not load KotlinBasePlugin in ${project.displayName} - ${ex::class.qualifiedName} ${ex.message}")
225-
logWarningIfKgpApplied(
228+
logKgpClassNotFoundWarning(
226229
project,
227230
kotlinBasePluginNotFoundException = ex,
228231
)
@@ -238,6 +241,8 @@ abstract class KotlinAdapter @Inject constructor(
238241
* Check all plugins to see if they are a subtype of [KotlinBasePlugin].
239242
* If any are, log a warning.
240243
*
244+
* Also, log an info message with the stacktrace of [kotlinBasePluginNotFoundException].
245+
*
241246
* ##### Motivation
242247
*
243248
* If the buildscript classpath is inconsistent, it might not be possible for DGP
@@ -247,22 +252,49 @@ abstract class KotlinAdapter @Inject constructor(
247252
*
248253
* @param[kotlinBasePluginNotFoundException] The exception thrown when [KotlinBasePlugin] is not available.
249254
*/
250-
private fun logWarningIfKgpApplied(
255+
private fun logKgpClassNotFoundWarning(
251256
project: Project,
252257
kotlinBasePluginNotFoundException: Throwable,
253258
) {
259+
// hide the stacktrace at `--info` log level, to avoid flooding the log
260+
logger.info(
261+
"Dokka Gradle Plugin could not load KotlinBasePlugin in ${project.displayName}",
262+
kotlinBasePluginNotFoundException,
263+
)
254264
PluginId.kgpPlugins.forEach { pluginId ->
255265
project.pluginManager.withPlugin(pluginId) {
256-
logger.warn(
257-
buildString {
258-
appendLine("Dokka Gradle Plugin could not load KotlinBasePlugin in ${project.displayName}, but plugin $id is applied.")
259-
appendLine("Check the buildscript classpath is consistent (all plugins are ")
260-
},
261-
kotlinBasePluginNotFoundException,
262-
)
266+
if (!projectsWithKgpClassNotFoundWarningApplied.add(project.path)) {
267+
logger.warn(
268+
"""
269+
|warning: Dokka could not load KotlinBasePlugin in ${project.displayName}, even though plugin $pluginId is applied.
270+
|The most common cause is a Gradle limitation: the plugins applied to subprojects should be consistent.
271+
|Please try the following:
272+
|1. Apply the Dokka and Kotlin plugins to the root project using the `plugins {}` DSL.
273+
| (If the root project does not need the plugins, use 'apply false')
274+
|2. Remove the Dokka and Kotlin plugins versions in the subprojects.
275+
|For more information see:
276+
| - https://docs.gradle.org/current/userguide/plugins_intermediate.html#sec:plugins_apply
277+
| - https://github.com/gradle/gradle/issues/25616
278+
| - https://github.com/gradle/gradle/issues/35117
279+
|Please report any feedback or problems https://kotl.in/dokka-issues
280+
|""".trimMargin()
281+
)
282+
} else {
283+
logger.lifecycle("project ${project.path} already applied Dokka Gradle Plugin's KotlinBasePlugin warning, skipping")
284+
}
263285
}
264286
}
265287
}
288+
289+
/**
290+
* Keep track of which projects have been warned by [logKgpClassNotFoundWarning],
291+
* otherwise it'll log the same warning multiple times for the same project, which is annoying.
292+
*
293+
* [logKgpClassNotFoundWarning] will be triggered multiple times because
294+
* [findKotlinBasePlugins] reacts to all [KotlinBasePlugin].
295+
* A project could have multiple plugins that implement this class.
296+
*/
297+
private val projectsWithKgpClassNotFoundWarningApplied: MutableSet<String> = newSetFromMap(ConcurrentHashMap())
266298
}
267299
}
268300

dokka-runners/dokka-gradle-plugin/src/testFunctional/kotlin/MultiModuleFunctionalTest.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import io.kotest.matchers.sequences.shouldNotBeEmpty
1717
import io.kotest.matchers.shouldBe
1818
import io.kotest.matchers.string.shouldBeEmpty
1919
import io.kotest.matchers.string.shouldContain
20+
import io.kotest.matchers.string.shouldContainOnlyOnce
2021
import io.kotest.matchers.string.shouldNotContain
2122
import org.gradle.testkit.runner.TaskOutcome.*
2223
import org.jetbrains.dokka.gradle.WorkerIsolation.ClassLoader
@@ -543,8 +544,8 @@ class MultiModuleFunctionalTest : FunSpec({
543544
// the subprojects should have KotlinAdapter applied, but the extension should be unavailable
544545
// because the buildscript classpath is inconsistent.
545546
// (DGP is applied to the root project, but KGP is not.)
546-
output shouldContain "Dokka Gradle Plugin could not load KotlinBasePlugin in project ':subproject-hello', but plugin org.jetbrains.kotlin.jvm is applied"
547-
output shouldContain "Dokka Gradle Plugin could not load KotlinBasePlugin in project ':subproject-goodbye', but plugin org.jetbrains.kotlin.jvm is applied"
547+
output shouldContainOnlyOnce "warning: Dokka could not load KotlinBasePlugin in project ':subproject-hello', even though plugin org.jetbrains.kotlin.jvm is applied."
548+
output shouldContainOnlyOnce "warning: Dokka could not load KotlinBasePlugin in project ':subproject-goodbye', even though plugin org.jetbrains.kotlin.jvm is applied."
548549
}
549550
}
550551
}

0 commit comments

Comments
 (0)