Mockito Java Agent Configuration for Future JDK Compatibility
Problem Statement
When running tests with Mockito in Spring Boot on JDK 21+, you may encounter warnings like these:
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK.
WARNING: A Java agent has been loaded dynamically (...)
WARNING: Dynamic loading of agents will be disallowed by default in a future release
These warnings occur because:
- Mockito uses
inline-mock-maker
which currently attaches itself as a Java agent at runtime - Newer JDK versions (21+) restrict dynamic agent loading for security and stability
- Future JDK releases will block this behavior by default
If unaddressed, tests will fail in upcoming JDK versions when Mockito's self-attachment mechanism is blocked.
Solution Overview
To maintain compatibility with current and future JDK versions:
- Explicitly load Mockito as a Java agent during test execution
- Disable class sharing with
-Xshare:off
to suppress related JDK warnings - Apply build-specific configurations (Maven/Gradle)
- Configure IDEs to inherit these changes
Maven Configuration
<build>
<plugins>
<!-- Optional: Keep mockito version consistent -->
<properties>
<mockito.version>5.14.2</mockito.version>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar
-Xshare:off
</argLine>
</configuration>
</plugin>
</plugins>
</build>
Key Points:
- Uses
settings.localRepository
to avoid hard-coded paths -Xshare:off
suppresses class-sharing warnings- Works across command-line and IDEs inheriting Maven configuration
- Explicit versioning prevents path resolution failures
Gradle Configuration
configurations {
mockitoAgent {
transitive = false
}
}
dependencies {
mockitoAgent "org.mockito:mockito-core:5.14.2"
}
test {
jvmArgs(
"-javaagent:${configurations.mockitoAgent.asPath}",
"-Xshare:off"
)
}
val mockitoAgent = configurations.create("mockitoAgent") {
isTransitive = false
}
dependencies {
mockitoAgent("org.mockito:mockito-core:5.14.2")
}
tasks.withType<Test> {
jvmArgs(
"-javaagent:${mockitoAgent.asPath}",
"-Xshare:off"
)
}
IDE-Specific Configuration
IntelliJ IDEA
- File > Settings > Build, Execution, Deployment > Build Tools > Gradle
- Set Run tests using to Gradle (not "IntelliJ IDEA")
- Verify Gradle JVM matches your project's JDK
Eclipse
Add VM arguments in Run Configuration:
- Run > Run Configurations > JUnit
- Select your test configuration or create new
- Add to VM Arguments:
-Xshare:off -javaagent:${env_var:userprofile}\.m2\repository\org\mockito\mockito-core\5.14.2\mockito-core-5.14.2.jar
How This Works
Explicit Agent Loading
- By specifying
-javaagent
, we bypass runtime self-attachment - Meets new JDK security requirements for explicit agent declaration
- By specifying
-Xshare:off
Purpose
Resolves OpenJDK class-sharing warnings:Sharing is only supported for boot loader classes...
- Disables class data sharing (CDS) to prevent classloader conflicts
- Required when combining Java agents with Spring Boot's classpath
Best Practices
Version Management
- Always specify
mockito-core
version explicitly - Keep versions consistent with Spring Boot dependencies
- Use property placeholders in Maven to ease updates
- Always specify
Environment Variables
For OS-independent paths in IDEs:- Windows:
${env_var:userprofile}\.m2\repository\...
- Unix/macOS:
${env_var:HOME}/.m2/repository/...
- Windows:
Verify Agent Path
Confirm agent JAR exists at specified location if errors occur
Troubleshooting
# Check agent availability
ls ${HOME}/.m2/repository/org/mockito/mockito-core/5.14.2
- Build fails with "agent not found": Verify your Maven local repository location
- Warnings persist in IDE: Confirm IDE is inheriting build tool configurations
- Maven fails on
@{argLine}
: Remove references to@{argLine}
if using older Maven versions
Important: Solutions requiring
@{argLine}
are incompatible with specific Maven/surefire combinations. The solution above avoids this issue entirely.