{"record":{"id":"8dd92f66d6ec4d90","repo":"quarkusio/quarkus","slug":"failed-to-acquire-handle-to-module-impladdopens-t","errorCode":null,"errorMessage":"Failed to acquire handle to Module#implAddOpens. This must be run with JVM parameter '--add-opens=java.base/java.lang.invoke=ALL-UNNAMED'","messagePattern":"Failed to acquire handle to Module#implAddOpens\\. This must be run with JVM parameter '--add-opens=java\\.base/java\\.lang\\.invoke=ALL-UNNAMED'","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/jvm/ReflectiveAccessModulesReconfigurer.java","lineNumber":80,"sourceCode":"            lookupField.setAccessible(true);\n\n            MethodHandles.Lookup privilegedLookup = (MethodHandles.Lookup) lookupField.get(null);\n\n            //Signature of the method we want to find\n            MethodType methodType = MethodType.methodType(void.class, String.class, Module.class);\n\n            //Use the privileged lookup to find the private method\n            handle = privilegedLookup.findVirtual(\n                    Module.class, // Class to find the method in\n                    \"implAddOpens\", // Name of the private method\n                    methodType // Signature of the method\n            );\n\n            logger.debug(\"Successfully acquired MethodHandle for implAddOpens.\");\n            return handle;\n\n        } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InaccessibleObjectException e) {\n            throw new RuntimeException(\"Failed to acquire handle to Module#implAddOpens. \" +\n                    \"This must be run with JVM parameter '--add-opens=java.base/java.lang.invoke=ALL-UNNAMED'\", e);\n        }\n    }\n\n    /**\n     * Uses the MethodHandle to open a package.\n     *\n     * @param sourceModule The module to open\n     * @param packageName The package to open\n     * @param targetModule The module to open to\n     */\n    private void addOpens(Module sourceModule, String packageName, Module targetModule) {\n        try {\n            implAddOpensHandle.invokeExact(sourceModule, packageName, targetModule);\n            logger.debugf(\"Successfully opened module %s/%s to %s\",\n                    sourceModule.getName(), packageName, targetModule.isNamed() ? targetModule.getName() : \"UNNAMED\");\n        } catch (Throwable e) {\n            // MethodHandle.invokeExact throws Throwable","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/jvm/ReflectiveAccessModulesReconfigurer.java#L62-L98","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\n./mvnw install\n// after\nexport MAVEN_OPTS=\"--add-opens=java.base/java.lang.invoke=ALL-UNNAMED\"\n./mvnw install","handlingStrategy":"validation","validationCode":"// Check the required add-opens is present before building\nString opts = System.getenv(\"MAVEN_OPTS\") == null ? \"\" : System.getenv(\"MAVEN_OPTS\");\nString jvm = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString();\nif (!(opts + jvm).contains(\"--add-opens=java.base/java.lang.invoke=ALL-UNNAMED\")) {\n    throw new IllegalStateException(\"Add --add-opens=java.base/java.lang.invoke=ALL-UNNAMED to the build JVM\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    // run the build\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"implAddOpens\")) {\n        throw new IllegalStateException(\"Re-run with: MAVEN_OPTS='--add-opens=java.base/java.lang.invoke=ALL-UNNAMED'\", e);\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["quarkus","jpms","add-opens","jdk","methodhandle"],"backgroundTag":"jpms-module-access-denied","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}