Skip to content
Latchkey

Gradle Test "does not open ... to unnamed module" - Fix --add-opens in CI

A Gradle test task fails on JDK 17+ because a test (or a library it uses) reflects into an encapsulated JDK package and the forked test JVM was not granted --add-opens. Strong encapsulation turns what was a warning on JDK 8/11 into a hard InaccessibleObjectException.

What this error means

The test task fails with Unable to make ... accessible: module java.base does not "opens java.lang" to unnamed module. The forked test JVM needs explicit --add-opens, which is not set in the Test task config.

gradle output
> Task :app:test FAILED
java.lang.reflect.InaccessibleObjectException: Unable to make field
java.lang.String.value accessible: module java.base does not "opens java.lang"
to unnamed module @4e0e2f2a

Diagnose it: get the real failure out of Gradle

Gradle summarises failures aggressively, and the top-level message frequently describes a downstream symptom rather than the cause. Re-run the failing task with diagnostics before changing build logic.

Terminal
# the actual stack, plus what Gradle decided about the build
./gradlew <task> --stacktrace --info

# is a stale daemon or cache involved?
./gradlew --stop
./gradlew <task> --no-daemon --no-build-cache

# what does Gradle think the environment is?
./gradlew -version

Common causes

Deep reflection in tests on an encapsulated package

A serialization/mock/proxy library used in tests reflects into java.base internals, which JDK 17 blocks unless the package is opened to the test JVM.

Test task not granted the needed --add-opens

The fix is per-JVM flags on the forked test JVM. Without jvmArgs("--add-opens ...") the test process denies the reflective access.

How to fix it

Add --add-opens to the Test task jvmArgs

Open the package(s) the tests reflect on to the forked test JVM.

build.gradle.kts
tasks.test {
    jvmArgs(
        "--add-opens", "java.base/java.lang=ALL-UNNAMED",
        "--add-opens", "java.base/java.util=ALL-UNNAMED"
    )
}

Prefer upgrading the offending library

If a dependency forces deep reflection, a newer JDK-17-compatible version often removes the need for --add-opens.

Terminal
./gradlew :app:dependencies --configuration testRuntimeClasspath
# identify the library doing deep reflection and bump it

Configuration cache and CI

  • The configuration cache rejects build logic that reads mutable state at execution time, which is why enabling it surfaces errors an existing build never showed.
  • Run with --configuration-cache-problems=warn first to see the full list rather than failing on the first one.
  • A cached configuration keyed to a different environment is worse than none. Include the JDK version in your cache key.

How to prevent it

  • Add the required --add-opens to the Test task jvmArgs.
  • Upgrade test/runtime libraries to JDK-17-compatible versions where possible.
  • Run tests on the target JDK so encapsulation errors surface early.

Frequently asked questions

What causes Gradle test "does not open ... to unnamed module"?
There are 2 common causes: deep reflection in tests on an encapsulated package and test task not granted the needed --add-opens. A serialization/mock/proxy library used in tests reflects into java.base internals, which JDK 17 blocks unless the package is opened to the test JVM.
How do I fix Gradle test "does not open ... to unnamed module"?
There are 2 fixes depending on which cause you have: add --add-opens to the test task jvmargs and prefer upgrading the offending library. Work through them in order, since the first is the most common.
What does Gradle test "does not open ... to unnamed module" actually mean?
The test task fails with Unable to make ...
How do I stop Gradle test "does not open ... to unnamed module" happening again?
Add the required --add-opens to the Test task jvmArgs. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card