This is an automated email from the ASF dual-hosted git repository.

mimaison pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 527467d0538 KAFKA-18356: Explicitly set up instrumentation for inline 
mocking (Java 21+) (#18339)
527467d0538 is described below

commit 527467d0538924cb4a5b99be890ef54c9063ee8a
Author: Ken Huang <[email protected]>
AuthorDate: Fri Sep 26 16:31:14 2025 +0800

    KAFKA-18356: Explicitly set up instrumentation for inline mocking (Java 
21+) (#18339)
    
    
    Reviewers: Mickael Maison <[email protected]>, Ismael Juma 
<[email protected]>
---
 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")
   }
 

Reply via email to