{"id":"a5fa8990e64f4866","repo":"apache/kafka","slug":"javadoc-jar-file-not-found-path-make-sure-the","errorCode":null,"errorMessage":"Javadoc JAR file not found: {path}. Make sure the javadoc task has run first.","messagePattern":"Javadoc JAR file not found: (.+?)\\. Make sure the javadoc task has run first\\.","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaPublicApiCheckerTask.java","lineNumber":81,"sourceCode":"        setGroup(\"verification\");\n        setDescription(\"Checks consistency between javadoc HTML files and @InterfaceAudience.Public annotations across project JARs\");\n\n        // Set default values\n        enabled.convention(true);\n        failOnViolation.convention(true);\n        reportFile.convention(getProject().getLayout().getBuildDirectory().file(\"reports/kafka-public-api-checker.txt\"));\n    }\n\n    @TaskAction\n    public void checkPublicApi() {\n        if (!getCheckerEnabled().get()) {\n            getLogger().info(\"KafkaPublicApiChecker is disabled, skipping...\");\n            return;\n        }\n\n        File jarFile = getJavadocJarFile();\n        if (!jarFile.exists()) {\n            throw new GradleException(\"Javadoc JAR file not found: \" + jarFile.getAbsolutePath() +\n                \". Make sure the javadoc task has run first.\");\n        }\n\n        getLogger().info(\"Checking public API consistency in: {}\", jarFile.getAbsolutePath());\n\n        try {\n            if (projectJarFiles.getFiles().isEmpty()) {\n                throw new GradleException(\n                        \"No project JARs configured on kafkaPublicApiChecker.projectJarFiles — \"\n                        + \"the checker needs at least one classes/jar source to build the API surface.\");\n            }\n            PublicApiChecker checker = new PublicApiChecker(\n                new ArrayList<>(projectJarFiles.getFiles()),\n                new ArrayList<>(referenceJarFiles.getFiles()));\n            CheckResult result = checker.checkPublicApiConsistency(jarFile);\n            List<PublicApiViolation> violations = result.violations();\n            List<PublicApiViolation> suppressions = result.suppressions();\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaPublicApiCheckerTask.java#L63-L99","documentation":"Thrown by KafkaPublicApiCheckerTask.checkPublicApi() when javadocJarPath resolves to a File whose exists() check returns false. The task compares @InterfaceAudience.Public annotations across project jars against the generated javadoc HTML, so it requires the javadoc jar to already exist on disk at task execution time. The message tells the user the configured path and points at the missing prerequisite task.","triggerScenarios":"Line 80-83: getJavadocJarFile() returns a path, but jarFile.exists() is false. Triggered when the plugin is configured with a javadocJarPath that points at a file the javadoc (or javadocJar) task never produced — e.g. the check task runs before javadocJar in the task graph, or the path was hand-set to a wrong location, or a clean wiped build/libs without re-running javadocJar.","commonSituations":"Running ./gradlew kafkaPublicApiCheck directly without depending on javadocJar; mis-configuring kafkaPublicApiChecker.javadocJarPath to a hardcoded path that diverges from the actual javadocJar output (e.g. wrong version suffix); CI that runs only the check task; a build scan after ./gradlew clean that skips the docs tasks.","solutions":["Run the javadocJar task first so the file exists: ./gradlew javadocJar kafkaPublicApiCheck.","If invoking the check task directly, make it depend on the producing task in the build script: tasks.named('kafkaPublicApiCheck').dependsOn('javadocJar').","Verify the configured path matches the actual output (e.g. build/libs/<project>-<version>-javadoc.jar); if javadocJarPath was hardcoded, point it at javadocJar.archiveFile instead.","If javadoc generation itself is failing or skipped, fix the upstream javadoc task (run ./gradlew javadoc --info) before re-running the checker."],"exampleFix":"// before\nkafkaPublicApiChecker {\n  javadocJarPath = layout.buildDirectory.file('libs/myapp-javadoc.jar') // wrong name\n}\n\n// after — wire to the producing task's output so it always exists and is up-to-date\nkafkaPublicApiChecker {\n  javadocJarPath = tasks.named('javadocJar', Jar).flatMap { it.archiveFile }\n}\ntasks.named('kafkaPublicApiCheck').configure { dependsOn('javadocJar') }","handlingStrategy":"validation","validationCode":"// Make the checker depend on javadocJar and verify the artifact exists before running\ntasks.named(\"kafkaPublicApiChecker\") { dependsOn(\"javadocJar\") }\nval jd = layout.buildDirectory.file(\"libs/${project.name}-${project.version}-javadoc.jar\").get().asFile\ncheck(jd.exists()) { \"javadoc jar missing at ${jd.absolutePath}; run :javadocJar first\" }","typeGuard":"fun File?.existingJar(): File? = this?.takeIf { it.exists() && it.isFile && it.extension == \"jar\" }","tryCatchPattern":null,"preventionTips":["Add dependsOn(\"javadocJar\") (or wire the task dependency in the plugin block) so Gradle always produces the jar before the checker runs.","Run ./gradlew javadocJar once after a clean to confirm the javadoc generation itself succeeds — a broken javadoc task yields no jar.","Do not delete the javadoc jar between the docsJar and checker tasks in a custom clean hook."],"tags":["gradle","kafka","api-checker","javadoc","task-ordering"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}