Files
ashwinpankajandClaude Opus 4.7 de8482a4e2 KAFKA-20779 KIP-1265 review follow-ups from #21337 (#22772)
## Summary

Follow-up nits from @chia7712's review of #21337. None affects checker
behaviour; grouped as a single small PR.

JIRA: [KAFKA-20779](https://issues.apache.org/jira/browse/KAFKA-20779)

## Changes

| # | File | Change | |---|------|--------| | 1 |
`core/…/PublicApiViolation.java` | `equals` uses
`Objects.equals(memberName, …)` instead of the ternary null-check. | | 2
| `core/…/CascadeValidator.java` | `asSuppression` omits `#member` when
the finding has no `memberName`, so class-scope `INVALID_SUPERTYPE`
suppressions no longer render as `…Owner#null`. Also uses ASCII hyphens
in the description separator. | | 3 |
`maven-plugin/…/KafkaInternalApiCheckerMojo.java` | Doc comments +
`@param` tags on the class default ctor + six setters;
`:maven-plugin:javadoc` is now warning-free. | | 4 |
`api-checker/build.gradle` | Adds `testLogging { events "passed",
"skipped", "failed" }` for consistency with the main Kafka build. | | 5
| `api-checker/README.md` | Documents `:maven-plugin:test`; layout tree
shows the test folder. |

Hooking `:api-checker:*:check` into the root `check` was dropped from
this PR per review — Kafka's CI relies on `kafka.test.xml.output.dir` +
`copyTestXml` to collect outputs from composite-included builds, so that
wiring needs a proper follow-up rather than being folded in here.

## Test plan
- [x] `./gradlew :api-checker:core:check
:api-checker:gradle-plugins:check :api-checker:maven-plugin:check` —
clean; all api-checker verification tasks pass.
- [x] `./gradlew :api-checker:maven-plugin:javadoc` — zero warnings.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-31 22:42:38 +08:00
..

Kafka API-checker plugins

This is a separate Gradle build (composite-included from the root settings.gradle via pluginManagement { includeBuild 'api-checker' }) that produces the KIP-1265 API checkers. Living outside Kafka's main build keeps the Maven runtime dependencies off the main-build classpath and lets each published artifact carry only the classes its consumers need.

Subproject Publishes Audience
:core org.apache.kafka:kafka-api-checker-core Shared scanner + validator + reporter (ASM only). Both plugin jars depend on it.
:gradle-plugins org.apache.kafka:kafka-internal-api-checker-gradle-plugin + plugin markers for org.apache.kafka.public-api-checker and org.apache.kafka.internal-api-checker The Kafka-internal producer-side checker and the published consumer-side Gradle checker.
:maven-plugin org.apache.kafka:kafka-internal-api-checker-maven-plugin Maven equivalent of the consumer-side checker.

End-user documentation (Gradle/Maven snippets, @SuppressKafkaInternalApiUsage, audience-inheritance rules) lives at docs/apis/internal-api-checker.md. The notes below cover building, testing, and publishing the plugins themselves.

Build

./gradlew :api-checker:core:build :api-checker:gradle-plugins:build :api-checker:maven-plugin:build

Test

./gradlew :api-checker:core:test :api-checker:gradle-plugins:test :api-checker:maven-plugin:test
  • :core:test — unit tests for the scanner, validators, and reporter, plus the shared testFixtures (AsmClassFactory, TempJarBuilder) they and the plugin tests use.
  • :gradle-plugins:test — includes a Gradle TestKit end-to-end test that applies the org.apache.kafka.internal-api-checker plugin to a synthetic consumer project.
  • :maven-plugin:test — hosts PluginXmlParityTest, which locks the generated plugin.xml Mojo descriptor against the fields on KafkaInternalApiCheckerMojo so adding a parameter without exposing it (or vice versa) fails locally.

Publish

Each subproject's publish task stages to the URL passed via -PmavenUrl (with -PmavenUsername / -PmavenPassword for credentials). The version is read from the repo-root gradle.properties, so release.py's existing updateVersion call sets it automatically. -PkafkaPluginsVersion=… overrides for one-off out-of-band publishes.

# Stage to ASF Nexus alongside the rest of an AK release
./gradlew :api-checker:core:publish \
         :api-checker:gradle-plugins:publish \
         :api-checker:maven-plugin:publish \
  -PmavenUrl=$ASF_NEXUS_STAGING_URL \
  -PmavenUsername=$NEXUS_USER \
  -PmavenPassword=$NEXUS_PASS

# Local smoke-test
./gradlew :api-checker:core:publishToMavenLocal \
         :api-checker:gradle-plugins:publishToMavenLocal \
         :api-checker:maven-plugin:publishToMavenLocal

The five published coordinates:

  • org.apache.kafka:kafka-api-checker-core:$KAFKA_VERSION — shared scanner library.
  • org.apache.kafka:kafka-internal-api-checker-gradle-plugin:$KAFKA_VERSION — Gradle plugin implementation jar (consumed by the marker poms).
  • org.apache.kafka.internal-api-checker:org.apache.kafka.internal-api-checker.gradle.plugin:$KAFKA_VERSION — marker pom for plugins { id 'org.apache.kafka.internal-api-checker' }.
  • org.apache.kafka.public-api-checker:org.apache.kafka.public-api-checker.gradle.plugin:$KAFKA_VERSION — marker pom for the producer-side checker. (Kafka-internal use, but published from the same module for consistency.)
  • org.apache.kafka:kafka-internal-api-checker-maven-plugin:$KAFKA_VERSION — Maven plugin (packaging maven-plugin).

Layout

api-checker/
├── settings.gradle           # declares the three subprojects
├── build.gradle              # group / version / signing / common publishing config
├── core/
│   ├── build.gradle          # ASM dep; published as kafka-api-checker-core
│   └── src/
│       ├── main/java/.../apicheck/                # scanner, validators, reporter
│       ├── test/java/.../apicheck/                # unit tests
│       └── testFixtures/java/.../apicheck/        # AsmClassFactory, TempJarBuilder
│                                                  # — re-used by :gradle-plugins' tests
├── gradle-plugins/
│   ├── build.gradle          # java-gradle-plugin; depends on :core
│   └── src/{main,test}/java/.../gradle/           # Plugin/Task/Extension × 2
└── maven-plugin/
    ├── build.gradle          # Maven deps; templates plugin.xml at processResources
    └── src/
        ├── main/
        │   ├── java/.../maven/KafkaInternalApiCheckerMojo.java
        │   └── resources/META-INF/maven/plugin.xml
        └── test/java/.../maven/PluginXmlParityTest.java   # locks plugin.xml ↔ Mojo fields