elastic/elasticsearch · error · IllegalArgumentException

Found src dir '${sourcesetName}' for Java ${version} but mul

Error message

Found src dir '${sourcesetName}' for Java ${version} but multi-release jar sourceset should have version ${minJavaVersion} or greater

What it means

Thrown by MrjarPlugin.findSourceVersions when scanning the project's src/ directory for multi-release-jar source sets named mainNN (two-digit version) and finding one whose NN is less than the build's minimum compiler version (minJavaVersion). MRJAR versioned sources must target Java >= minJavaVersion so the versioned directory is a strict superset; a lower version duplicates the baseline without benefit and is rejected. A special exception: mainNN == minJavaVersion is allowed (the check is '<', not '<=') to permit incubating-module usage without preview warnings.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/MrjarPlugin.java:243

        project.getTasks().named("check").configure(checkTask -> checkTask.dependsOn(testTaskProvider));
    }

    private static List<Integer> findSourceVersions(Project project, int minJavaVersion) {
        var srcDir = project.getProjectDir().toPath().resolve("src");
        List<Integer> versions = new ArrayList<>();
        try (var subdirStream = Files.list(srcDir)) {
            for (Path sourceSetPath : subdirStream.toList()) {
                assert Files.isDirectory(sourceSetPath);
                String sourcesetName = sourceSetPath.getFileName().toString();
                Matcher sourcesetMatcher = MRJAR_SOURCESET_PATTERN.matcher(sourcesetName);
                if (sourcesetMatcher.matches()) {
                    int version = Integer.parseInt(sourcesetMatcher.group(1));
                    if (version < minJavaVersion) {
                        // NOTE: We allow mainNN for the min java version so that incubating modules can be used without warnings.
                        // It is a workaround for https://bugs.openjdk.org/browse/JDK-8187591. Once min java is 22, we
                        // can use the SuppressWarnings("preview") in the code using incubating modules and this check
                        // can change to <=
                        throw new IllegalArgumentException(
                            "Found src dir '"
                                + sourcesetName
                                + "' for Java "
                                + version
                                + " but multi-release jar sourceset should have version "
                                + minJavaVersion
                                + " or greater"
                        );
                    }
                    versions.add(version);
                }
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }

        Collections.sort(versions);
        return versions;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove or rename the offending src/mainNN directory so NN >= minJavaVersion (the build's minimum compiler major version).
  2. If the versioned sources are still relevant, bump NN to the current minJavaVersion (e.g. migrate src/main11 contents into src/main21 or into main).
  3. If the directory is not an MRJAR source set, rename it so it does not match 'main(\d{2})'.
  4. After raising the build's minJavaVersion, sweep the tree for stale mainNN directories.

Example fix

// before: build min compiler version is 21, but this dir exists
//   src/main17/Foo.java
// after: remove it, or move contents into src/main/ or src/main21/
Defensive patterns

Strategy: validation

Validate before calling

import java.util.regex.Pattern;
private static final Pattern MRJAR = Pattern.compile("main(\\d{2})");
int minJavaVersion = Integer.parseInt(
    buildParams.getMinimumCompilerVersion().getMajorVersion());
for (Path p : Files.list(projectDir.toPath().resolve("src")).toList()) {
    var m = MRJAR.matcher(p.getFileName().toString());
    if (m.matches() && Integer.parseInt(m.group(1)) < minJavaVersion) {
        throw new IllegalStateException(
            "stale MRJAR source set " + p + " (< min java " + minJavaVersion + ")");
    }
}

Prevention

When it happens

Trigger: findSourceVersions lists direct children of src/, matches each name against MRJAR_SOURCESET_PATTERN 'main(\d{2})', parses the captured number, and throws if version < minJavaVersion. minJavaVersion is derived from buildParams.getMinimumCompilerVersion().getMajorVersion().

Common situations: Creating a src/main17 directory while the build's minimum compiler version is 21; reusing an old versioned source dir after a min-version bump (e.g. the build moved to JDK 21 but src/main11 still exists); naming a directory 'main09' or 'main11' inadvertently.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/63eef7725e967d16. Report an issue: GitHub.