apache/kafka · error · GradleException

No project JARs configured on kafkaPublicApiChecker.projectJ

Error message

No project JARs configured on kafkaPublicApiChecker.projectJarFiles — the checker needs at least one classes/jar source to build the API surface.

What it means

Thrown by KafkaPublicApiCheckerTask.checkPublicApi() when projectJarFiles resolves to an empty file collection. The checker constructs its API surface from the classes/jars in projectJarFiles (line 93-95), so an empty collection means there is nothing to compare against the javadoc jar and the check is meaningless. Unlike javadocJarPath, projectJarFiles has no convention default — the build script or plugin must populate it explicitly.

Source

Thrown at api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaPublicApiCheckerTask.java:89

    @TaskAction
    public void checkPublicApi() {
        if (!getCheckerEnabled().get()) {
            getLogger().info("KafkaPublicApiChecker is disabled, skipping...");
            return;
        }

        File jarFile = getJavadocJarFile();
        if (!jarFile.exists()) {
            throw new GradleException("Javadoc JAR file not found: " + jarFile.getAbsolutePath() +
                ". Make sure the javadoc task has run first.");
        }

        getLogger().info("Checking public API consistency in: {}", jarFile.getAbsolutePath());

        try {
            if (projectJarFiles.getFiles().isEmpty()) {
                throw new GradleException(
                        "No project JARs configured on kafkaPublicApiChecker.projectJarFiles — "
                        + "the checker needs at least one classes/jar source to build the API surface.");
            }
            PublicApiChecker checker = new PublicApiChecker(
                new ArrayList<>(projectJarFiles.getFiles()),
                new ArrayList<>(referenceJarFiles.getFiles()));
            CheckResult result = checker.checkPublicApiConsistency(jarFile);
            List<PublicApiViolation> violations = result.violations();
            List<PublicApiViolation> suppressions = result.suppressions();

            // Generate report
            ViolationReporter reporter = new ViolationReporter();
            File report = reportFile.get().getAsFile();
            reporter.writeTextReport(violations, suppressions, report);

            // Print summary to console
            reporter.printToConsole(violations, suppressions);

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Wire projectJarFiles to the project's main jar output: kafkaPublicApiChecker.projectJarFiles.from(tasks.named('jar')).
  2. If the module legitimately produces no jar (bom/aggregator), don't apply the plugin to that subproject — apply it inside a subprojects {} block filtered to modules with a jar task.
  3. Confirm the source configuration actually has artifacts by printing it: println kafkaPublicApiChecker.projectJarFiles.files before the check.
  4. If multiple outputs are needed, add them all: kafkaPublicApiChecker.projectJarFiles.from(tasks.named('jar'), configurations.runtimeClasspath.filter { it.name.startsWith('kafka') }).

Example fix

// before
plugins { id 'org.apache.kafka.kafka-public-api-checker' }
// projectJarFiles never configured -> empty

// after
plugins { id 'org.apache.kafka.kafka-public-api-checker' }

kafkaPublicApiChecker {
  projectJarFiles.from(tasks.named('jar'))
}
Defensive patterns

Strategy: validation

Validate before calling

// Configure projectJarFiles from the project's own jar output
tasks.named<org.apache.kafka.gradle.KafkaPublicApiCheckerTask>("kafkaPublicApiChecker").configure {
    projectJarFiles.from(tasks.named<Jar>("jar").get().archiveFile)
}
check(tasks.named<org.apache.kafka.gradle.KafkaPublicApiCheckerTask>("kafkaPublicApiChecker").get().projectJarFiles.files.isNotEmpty()) {
    "kafkaPublicApiChecker.projectJarFiles is empty; wire it to the project's jar/archive output."
}

Prevention

When it happens

Trigger: Line 88-92: projectJarFiles.getFiles().isEmpty() is true inside the try block. Reached when the plugin is applied without configuring kafkaPublicApiChecker.projectJarFiles, or when the configured from(...) source resolves to no files (e.g. a configuration that has no dependencies, or a tasks.named('jar') reference whose task has not produced output yet).

Common situations: Applying the plugin to a new subproject but forgetting to wire projectJarFiles.from(tasks.named('jar')); using a custom configuration that turned out empty; a multi-module root that applies the plugin to allprojects including ones that produce no main jar (e.g. aggregator/bom modules); renaming the jar task so the from(...) reference points at nothing.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/59248298df5f7264.json. Report an issue: GitHub.