Skip to content

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:

  1. Mockito uses inline-mock-maker which currently attaches itself as a Java agent at runtime
  2. Newer JDK versions (21+) restrict dynamic agent loading for security and stability
  3. 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:

  1. Explicitly load Mockito as a Java agent during test execution
  2. Disable class sharing with -Xshare:off to suppress related JDK warnings
  3. Apply build-specific configurations (Maven/Gradle)
  4. Configure IDEs to inherit these changes

Maven Configuration

xml
<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

groovy
configurations {
    mockitoAgent {
        transitive = false
    }
}

dependencies {
    mockitoAgent "org.mockito:mockito-core:5.14.2"
}

test {
    jvmArgs(
        "-javaagent:${configurations.mockitoAgent.asPath}",
        "-Xshare:off"
    )
}
kotlin
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

  1. File > Settings > Build, Execution, Deployment > Build Tools > Gradle
  2. Set Run tests using to Gradle (not "IntelliJ IDEA")
  3. Verify Gradle JVM matches your project's JDK

Eclipse

Add VM arguments in Run Configuration:

  1. Run > Run Configurations > JUnit
  2. Select your test configuration or create new
  3. 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

  1. Explicit Agent Loading

    • By specifying -javaagent, we bypass runtime self-attachment
    • Meets new JDK security requirements for explicit agent declaration
  2. -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

  1. Version Management

    • Always specify mockito-core version explicitly
    • Keep versions consistent with Spring Boot dependencies
    • Use property placeholders in Maven to ease updates
  2. Environment Variables
    For OS-independent paths in IDEs:

    • Windows: ${env_var:userprofile}\.m2\repository\...
    • Unix/macOS: ${env_var:HOME}/.m2/repository/...
  3. Verify Agent Path
    Confirm agent JAR exists at specified location if errors occur

Troubleshooting

shell
# 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.