elastic/elasticsearch · error · GradleException

Native-image classpath is empty

Error message

Native-image classpath is empty

What it means

Thrown inside NativeImageBuildAction.execute() when the classpath file collection, after filtering with File::exists, contains zero entries. The classpath is passed to native-image inside a Docker container. If every JAR or directory on the classpath does not exist on the filesystem, the filtered list is empty and the build fails before launching Docker.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/docker/NativeImageBuildTask.java:162

            this.execOperations = execOperations;
        }

        @Override
        public void execute() {
            Parameters params = getParameters();
            String imageTag = params.getImageTag().get();
            String platform = params.getPlatform().get();
            String mainClass = params.getMainClass().get();
            File outputFile = params.getOutputFile().get().getAsFile();
            File outputDir = outputFile.getParentFile();

            if (outputDir.exists() == false && outputDir.mkdirs() == false) {
                throw new GradleException("Failed to create output directory: " + outputDir);
            }

            List<File> classpathFiles = params.getClasspath().getFiles().stream().filter(File::exists).collect(Collectors.toList());
            if (classpathFiles.isEmpty()) {
                throw new GradleException("Native-image classpath is empty");
            }

            // Build classpath string for inside the container: /cp/0:/cp/1:...
            List<String> cpPaths = new ArrayList<>();
            for (int i = 0; i < classpathFiles.size(); i++) {
                cpPaths.add("/cp/" + i);
            }
            // Container is always Linux
            String cpString = String.join(":", cpPaths);

            List<String> args = new ArrayList<>();
            args.add("run");
            args.add("--rm");
            for (int i = 0; i < classpathFiles.size(); i++) {
                File f = classpathFiles.get(i);
                String path = f.getAbsolutePath();
                if (File.separatorChar == '\\') {
                    path = path.replace("\\", "/");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Ensure the task declares proper dependencies on the tasks that produce its classpath: nativeImageBuild.dependsOn(jar) or use the configuration's builtOutputs.
  2. Check that the classpath configuration resolves to real artifacts: ./gradlew dependencies --configuration <configName>.
  3. If classpath entries are output directories, ensure the corresponding compile task runs first by wiring dependsOn.
  4. Run a clean full build to regenerate all artifacts: ./gradlew clean assemble.

Example fix

// before
tasks.named('nativeImageBuild') {
    classpath = sourceSets.main.runtimeClasspath // may not be resolved yet
}

// after
tasks.named('nativeImageBuild') {
    classpath = sourceSets.main.runtimeClasspath
    dependsOn(tasks.named('jar')) // ensure artifacts exist
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate classpath before task execution
List<File> existing = classpath.getFiles().stream().filter(File::exists).collect(Collectors.toList());
if (existing.isEmpty()) {
    throw new GradleException("Classpath is empty — ensure producing tasks have run: " + classpath.getFiles());
}

Prevention

When it happens

Trigger: params.getClasspath().getFiles() returns a set of File objects, but none of them exist on disk. This happens when the classpath is configured from a configuration whose dependencies have not been resolved/downloaded, when the task runs before its classpath-producing dependency, or when the classpath references stale or cleaned-up artifacts.

Common situations: The task depends on a JAR that was never built because its producing task was skipped or excluded. The Gradle build cache or a clean operation removed intermediate artifacts. The classpath configuration is misconfigured to reference output directories that don't exist yet (e.g., a source set's output before compilation).

Related errors


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