quarkusio/quarkus · error · RuntimeException
Failed to acquire handle to Module#implAddOpens. This must b
Error message
Failed to acquire handle to Module#implAddOpens. This must be run with JVM parameter '--add-opens=java.base/java.lang.invoke=ALL-UNNAMED'
What it means
ReflectiveAccessModulesReconfigurer obtains a MethodHandle to the internal Module#implAddOpens method (via java.lang.invoke lookup tricks) so it can open JPMS packages without an agent. If the reflective lookup fails (NoSuchFieldException/NoSuchMethodException/IllegalAccessException/InaccessibleObjectException) it throws this RuntimeException telling you the JVM must be started with --add-opens=java.base/java.lang.invoke=ALL-UNNAMED.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/jvm/ReflectiveAccessModulesReconfigurer.java:80
lookupField.setAccessible(true);
MethodHandles.Lookup privilegedLookup = (MethodHandles.Lookup) lookupField.get(null);
//Signature of the method we want to find
MethodType methodType = MethodType.methodType(void.class, String.class, Module.class);
//Use the privileged lookup to find the private method
handle = privilegedLookup.findVirtual(
Module.class, // Class to find the method in
"implAddOpens", // Name of the private method
methodType // Signature of the method
);
logger.debug("Successfully acquired MethodHandle for implAddOpens.");
return handle;
} catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InaccessibleObjectException e) {
throw new RuntimeException("Failed to acquire handle to Module#implAddOpens. " +
"This must be run with JVM parameter '--add-opens=java.base/java.lang.invoke=ALL-UNNAMED'", e);
}
}
/**
* Uses the MethodHandle to open a package.
*
* @param sourceModule The module to open
* @param packageName The package to open
* @param targetModule The module to open to
*/
private void addOpens(Module sourceModule, String packageName, Module targetModule) {
try {
implAddOpensHandle.invokeExact(sourceModule, packageName, targetModule);
logger.debugf("Successfully opened module %s/%s to %s",
sourceModule.getName(), packageName, targetModule.isNamed() ? targetModule.getName() : "UNNAMED");
} catch (Throwable e) {
// MethodHandle.invokeExact throws ThrowableView on GitHub (pinned to e1c734241f)
Solutions
- Add --add-opens=java.base/java.lang.invoke=ALL-UNNAMED to the JVM running the build: export MAVEN_OPTS="--add-opens=java.base/java.lang.invoke=ALL-UNNAMED"
- For Gradle, set org.gradle.jvmargs in gradle.properties to include the same --add-opens flag
- For IDE runs/tests, add the flag to the JUnit/test JVM arguments (e.g. quarkus.test.arg-line or surefire argLine)
- Use a JDK version officially supported by your Quarkus release, where the flag is not needed or documented
Example fix
// before ./mvnw install // after export MAVEN_OPTS="--add-opens=java.base/java.lang.invoke=ALL-UNNAMED" ./mvnw install
Defensive patterns
Strategy: validation
Validate before calling
// Check the required add-opens is present before building
String opts = System.getenv("MAVEN_OPTS") == null ? "" : System.getenv("MAVEN_OPTS");
String jvm = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString();
if (!(opts + jvm).contains("--add-opens=java.base/java.lang.invoke=ALL-UNNAMED")) {
throw new IllegalStateException("Add --add-opens=java.base/java.lang.invoke=ALL-UNNAMED to the build JVM");
} Try / catch
try {
// run the build
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("implAddOpens")) {
throw new IllegalStateException("Re-run with: MAVEN_OPTS='--add-opens=java.base/java.lang.invoke=ALL-UNNAMED'", e);
}
throw e;
} Prevention
- Set MAVEN_OPTS=--add-opens=java.base/java.lang.invoke=ALL-UNNAMED in CI and locally
- Mirror the flag in Gradle org.gradle.jvmargs and surefire/Quarkus test arg-line
- Keep IDE-launched builds configured with the same JVM flags
- Use a Quarkus-supported JDK version
When it happens
Trigger: The build JVM's module system blocks deep reflection into java.lang.invoke: the hidden lookup for Module.implAddOpens cannot access the field/method, which happens on JDKs without the necessary --add-opens flag (especially JDK 16+ strong encapsulation).
Common situations: Running the build on a newer JDK where --add-opens=java.base/java.lang.invoke=ALL-UNNAMED was not propagated (MAVEN_OPTS, gradle.properties, test JVM args); container images with stripped-down JDKs; IDE-launched builds that drop JVM args.
Related errors
- Failed to invoke implAddOpens
- Failed to redefine module ${moduleName}
- Quarkus applications require Java 21 or higher to build
- You're not expected to use the unnamed module as identifier
- At least one package name must be specified
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/8dd92f66d6ec4d90.
Report an issue: GitHub.