From 527467d0538924cb4a5b99be890ef54c9063ee8a Mon Sep 17 00:00:00 2001 From: Ken Huang Date: Fri, 26 Sep 2025 16:31:14 +0800 Subject: [PATCH] KAFKA-18356: Explicitly set up instrumentation for inline mocking (Java 21+) (#18339) Reviewers: Mickael Maison , Ismael Juma --- build.gradle | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 753a86cfc35..29537dd77dc 100644 --- a/build.gradle +++ b/build.gradle @@ -157,7 +157,7 @@ ext { libs.log4j2Api, libs.log4j2Core ] - + } allprojects { @@ -484,11 +484,36 @@ subprojects { } } + // Workaround for Mockito Java Agent restrictions in Java 21+ + // Starting with Java 21, the JDK restricts libraries from attaching a Java agent + // to their own JVM. As a result, Mockito’s inline mock maker (mockito-core) + // fails without explicit instrumentation, and the JVM consistently emits warnings. + // See also: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#mockito-instrumentation + afterEvaluate { subproject -> + def hasMockitoCore = subproject.configurations.findAll { + it.canBeResolved + }.any { config -> + config.incoming.dependencies.any { dependency -> + "$dependency" == libs.mockitoCore + } + } + + if (hasMockitoCore) { + subproject.configurations { + mockitoAgent { + transitive = false + } + } + subproject.dependencies { + mockitoAgent libs.mockitoCore + } + } + } + // The suites are for running sets of tests in IDEs. // Gradle will run each test class, so we exclude the suites to avoid redundantly running the tests twice. def testsToExclude = ['**/*Suite.class'] - // This task will copy JUnit XML files out of the sub-project's build directory and into // a top-level build/junit-xml directory. This is necessary to avoid reporting on tests which // were not run, but instead were restored via FROM-CACHE. See KAFKA-17479 for more details. @@ -518,6 +543,14 @@ subprojects { } test { + + doFirst { + def mockitoAgentConfig = configurations.findByName('mockitoAgent') + if (mockitoAgentConfig) { + jvmArgs("-javaagent:${mockitoAgentConfig.asPath}") + } + } + maxParallelForks = maxTestForks ignoreFailures = userIgnoreFailures @@ -551,7 +584,7 @@ subprojects { maxFailures = userMaxTestRetryFailures } } - + finalizedBy("copyTestXml") }