{"record":{"id":"1c6414a16c9152af","repo":"elastic/elasticsearch","slug":"module-info-class-no-found-in-path","errorCode":null,"errorMessage":"module-info.class no found in ${path}","messagePattern":"module-info\\.class no found in (.+?)","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java","lineNumber":119,"sourceCode":"                    try {\n                        assertAllESJarsAreModular(libPath);\n                        assertAllModulesPresent(libPath);\n                    } catch (IOException e) {\n                        throw new UncheckedIOException(e);\n                    }\n                }\n            });\n        });\n    }\n\n    /** Checks that all expected ES jar files are modular, i.e. contain a module-info.class in their root. */\n    private static void assertAllESJarsAreModular(Path libPath) throws IOException {\n        try (var s = Files.walk(libPath, 1)) {\n            s.filter(Files::isRegularFile).filter(isESJar).filter(isNotExcluded).sorted().forEach(path -> {\n                try (JarFile jf = new JarFile(path.toFile())) {\n                    JarEntry entry = jf.getJarEntry(MODULE_INFO);\n                    if (entry == null) {\n                        throw new GradleException(MODULE_INFO + \" no found in \" + path);\n                    }\n                } catch (IOException e) {\n                    throw new GradleException(\"Failed when reading jar file \" + path, e);\n                }\n            });\n        }\n    }\n\n    /** Checks that all expected Elasticsearch modules are present. */\n    private static void assertAllModulesPresent(Path libPath) {\n        List<String> actualESModules = ModuleFinder.of(libPath).findAll().stream().filter(isESModule).map(toName).sorted().toList();\n        if (actualESModules.equals(EXPECTED_ES_SERVER_MODULES) == false) {\n            throw new GradleException(\n                \"expected modules \" + listToString(EXPECTED_ES_SERVER_MODULES) + \", \\nactual modules \" + listToString(actualESModules)\n            );\n        }\n    }\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java#L101-L137","documentation":"Thrown as GradleException by assertAllESJarsAreModular() when an Elasticsearch JAR (name starting 'elasticsearch-', excluding elasticsearch-log4j) in the lib/ directory does not contain a module-info.class entry at its root. ES server jars must be modular JPMS modules; a missing module-info means the jar was built without module info, breaking the module system checks and runtime module resolution. Note: the message has a typo ('no found' instead of 'not found').","triggerScenarios":"assertAllESJarsAreModular (line 113) walks lib/ depth 1, filters for regular files starting with 'elasticsearch-' (excluding 'elasticsearch-log4j'), opens each as a JarFile, and checks getJarEntry(\"module-info.class\"). A null entry throws at line 119.","commonSituations":"A new ES subproject jar was added to the distribution but its build.gradle doesn't apply the module plugin or generate module-info; a third-party shadow jar was renamed to start with 'elasticsearch-'; the modularization step was skipped in the build; refactoring merged a module into a non-modular jar.","solutions":["Add a module-info.java to the source set of the project producing the offending jar.","Ensure the project applies the ES module/plugin conventions that generate module-info.class during jar task.","If the jar is legitimately non-modular, add its name prefix to ES_JAR_EXCLUDES (currently only elasticsearch-log4j).","Rebuild the jar task and verify with 'jar tf <jar> | grep module-info.class'."],"exampleFix":"// before: new subproject jar lacks module-info\nevaluationDependsOn(':libs:elasticsearch-newlib')\n// jar contains no module-info.class → throws\n\n// after: add module-info.java to src/main/java\n// module org.elasticsearch.newlib { exports org.elasticsearch.newlib; }\n// and ensure the jar task includes it (default for src/main/java)","handlingStrategy":"validation","validationCode":"try (JarFile jf = new JarFile(path.toFile())) {\n    if (jf.getJarEntry(\"module-info.class\") == null) {\n        System.err.println(\"WARNING: \" + path + \" is not modular (no module-info.class)\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add module-info.java to every ES subproject that produces a jar shipped in lib/.","Apply the ES module conventions plugin to new subprojects.","If a jar is intentionally non-modular, add its prefix to ES_JAR_EXCLUDES.","Run 'jar tf <jar> | grep module-info' after adding new jars to the distribution."],"tags":["distribution","modules","jpms","modularization","validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}