{"id":"21945462c718f247","repo":"apache/kafka","slug":"failed-to-check-internal-api-usage-errormessage-219454","errorCode":null,"errorMessage":"Failed to check internal API usage: {errorMessage}","messagePattern":"Failed to check internal API usage: (.+?)","errorType":"exception","errorClass":"MojoExecutionException","httpStatus":null,"severity":"error","filePath":"api-checker/maven-plugin/src/main/java/org/apache/kafka/maven/KafkaInternalApiCheckerMojo.java","lineNumber":145,"sourceCode":"    private void handleNoKafkaDependency() throws MojoFailureException {\n        String msg = \"No org.apache.kafka:* dependencies found on the project classpath. \"\n                + \"The checker cannot derive an API surface and would produce a meaningless \"\n                + \"'0 violations' report — likely a classpath or configuration issue.\";\n        if (failOnNoKafkaDependency) {\n            throw new MojoFailureException(msg);\n        }\n        getLog().warn(msg + \" Skipping internal API check. \"\n                + \"Set <failOnNoKafkaDependency>true</failOnNoKafkaDependency> to make this fatal.\");\n    }\n\n    private void runCheck(List<File> kafkaJars, List<File> classRoots)\n            throws MojoExecutionException, MojoFailureException {\n        try {\n            getLog().info(\"Scanning \" + classRoots.size() + \" class file root(s) for internal API usage\");\n            CheckResult result = new PublicApiChecker(kafkaJars).checkBytecode(classRoots);\n            reportResults(result);\n        } catch (IOException e) {\n            throw new MojoExecutionException(\"Failed to check internal API usage: \" + e.getMessage(), e);\n        }\n    }\n\n    private void reportResults(CheckResult result) throws MojoFailureException, IOException {\n        List<PublicApiViolation> violations = result.violations();\n        List<PublicApiViolation> suppressions = result.suppressions();\n\n        ViolationReporter reporter = new ViolationReporter();\n        reporter.writeTextReport(violations, suppressions, reportFile);\n        reporter.printToConsole(violations, suppressions);\n\n        getLog().info(\"Internal API usage check completed. Report written to: \" + reportFile.getAbsolutePath());\n\n        long unjustified = suppressions.stream().filter(PublicApiViolation::lacksReason).count();\n        if (unjustified > 0) {\n            getLog().warn(unjustified + \" suppression(s) carry no reason — KIP-1265 requires a justification on every @SuppressKafkaInternalApiUsage\");\n        }\n","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/api-checker/maven-plugin/src/main/java/org/apache/kafka/maven/KafkaInternalApiCheckerMojo.java#L127-L163","documentation":"Wrapped I/O failure raised by KafkaInternalApiCheckerMojo.runCheck() when PublicApiChecker.checkBytecode(classRoots) throws an IOException. The original IOException is set as the cause of the MojoExecutionException and its message is appended. Like the Gradle analogue, this is an infrastructure error reading the kafka jars or scanning the project's compiled class output — not an internal-API violation.","triggerScenarios":"Lines 142-146 of runCheck(): a PublicApiChecker construction or checkBytecode call throws IOException. Triggers include a corrupt or concurrently-modified kafka dependency jar in the local Maven repo (~/.m2/repository), a missing/partial build output directory (default ${project.build.outputDirectory}), a permission-denied read on a .class file, or a closed/truncated jar stream.","commonSituations":"A previous mvn install was interrupted leaving a partial jar in ~/.m2/repository/org/apache/kafka/...; CI on a container with read-only or NFS-mounted target/; concurrent mvn invocations mutating the same target/; antivirus locking class files on Windows; disk-full truncating compiled output.","solutions":["Clean and re-run: mvn clean verify -o to rebuild target/ from scratch and rule out partial output.","If the cause names a jar in ~/.m2/repository, re-resolve it: mvn dependency:purge-local-repository -DreResolve=true or delete the specific org.apache.kafka artifact directory and let Maven re-download.","Inspect the IOException cause for the exact path, then verify it (ls -l, jar tf <jar>, unzip -t <jar>) and fix permissions / free disk / re-fetch.","Run with a single Maven process (no parallel concurrent builds touching the same target/) and on a local filesystem rather than NFS.","If using mvn -T (parallel), verify two modules aren't sharing an output dir or local-repo path."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Ensure the report file's parent exists and class output is present before execute()\nFile reportDir = reportFile.getParentFile();\nif (!reportDir.exists() && !reportDir.mkdirs()) {\n    throw new IllegalStateException(\"Cannot create report dir: \" + reportDir);\n}","typeGuard":null,"tryCatchPattern":"try {\n    mojo.execute();\n} catch (org.apache.maven.plugin.MojoExecutionException e) {\n    if (e.getMessage().startsWith(\"Failed to check internal API usage\") && e.getCause() instanceof java.io.IOException) {\n        getLog().warn(\"Internal API check skipped (transient IO: \" + e.getCause().getMessage() + \"); rerun the build.\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Run mvn clean before verify if the target/ directory is stale or was produced by a different JDK — corrupted class files cause IOException during scanning.","Do not delete target/classes between compile and verify phases; the mojo scans those compiled roots.","Ensure the reportFile path (default target/reports/...) is writable and not locked by another process during the verify phase."],"tags":["maven","kafka","api-checker","io","filesystem"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}