{"record":{"id":"a1665421a8f14766","repo":"elastic/elasticsearch","slug":"module-module-getname-does-not-contain-qualifi","errorCode":null,"errorMessage":"Module {module.getName()} does not contain qualified exports or opens for module {targetName}","messagePattern":"Module (.+?) does not contain qualified exports or opens for module (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/core/src/main/java/org/elasticsearch/jdk/ModuleQualifiedExportsService.java","lineNumber":146,"sourceCode":"        targetsToSources.replaceAll((k, v) -> List.copyOf(v));\n        return Map.copyOf(targetsToSources);\n    }\n\n    /**\n     * Returns all qualified targets of the owning module.\n     */\n    public Set<String> getTargets() {\n        return targets;\n    }\n\n    /**\n     * Add exports and opens for a target module.\n     * @param target A module whose name exists in {@link #getTargets()}\n     */\n    public void addExportsAndOpens(Module target) {\n        String targetName = target.getName();\n        if (targets.contains(targetName) == false) {\n            throw new IllegalArgumentException(\n                \"Module \" + module.getName() + \" does not contain qualified exports or opens for module \" + targetName\n            );\n        }\n        List<String> exports = qualifiedExports.getOrDefault(targetName, List.of());\n        for (String export : exports) {\n            addExports(export, target);\n        }\n        List<String> opens = qualifiedOpens.getOrDefault(targetName, List.of());\n        for (String open : opens) {\n            addOpens(open, target);\n        }\n    }\n\n    /**\n     * Add a qualified export. This should always be implemented as follows:\n     * <code>\n     *     module.addExports(pkg, target);\n     * </code>","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/core/src/main/java/org/elasticsearch/jdk/ModuleQualifiedExportsService.java#L128-L164","documentation":"Thrown by ModuleQualifiedExportsService.addExportsAndOpens when the target Module's name is not present in the precomputed 'targets' set of qualified-export recipients. The service is built from a module's descriptor listing which packages it qualified-exports/opens to specific named modules; attempting to wire exports to a module that was never declared as a qualified recipient is rejected. This guards the Java module-system reflection used to give ES internals access into JDK modules.","triggerScenarios":"Calling addExportsAndOpens(target) with a Module whose getName() is not in the targets set populated from the module descriptor's qualified exports and opens. The guard fires before any addExports/addOpens reflection call.","commonSituations":"Wiring a new target module without declaring a qualified export for it in module-info; renaming a module without updating the descriptor; passing the wrong Module instance (e.g. an unnamed or test module) to a service configured for a named one.","solutions":["Add a 'exports <pkg> to <targetName>' or 'opens <pkg> to <targetName>' directive in the source module's module-info.java.","Verify the Module passed to addExportsAndOpens is the intended named module (check target.getName() against the descriptor).","Rebuild the module so the updated descriptor is picked up."],"exampleFix":"// before: module-info.java has no qualified export to 'org.elasticsearch.foo'\nmodule org.elasticsearch.core {\n  exports org.elasticsearch.core;\n}\n\n// after\nmodule org.elasticsearch.core {\n  exports org.elasticsearch.core to org.elasticsearch.foo;\n  opens org.elasticsearch.core to org.elasticsearch.foo;\n}","handlingStrategy":"validation","validationCode":"// Before calling addExportsAndOpens, verify the target is registered\nModuleQualifiedExportsService svc = ...;\nModule target = ...;\nif (!svc.getTargets().contains(target.getName())) {\n  throw new IllegalStateException(\"module \" + target.getName() + \" is not a declared qualified target\");\n}\nsvc.addExportsAndOpens(target);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep module-info.java qualified exports/opens in sync with every target module you wire at runtime.","Add a build-time test that asserts getTargets() contains each module you intend to wire."],"tags":["jpms","module-system","exports","reflection"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}