Skip to content

KIP-1320 (PoC): deprecation approach for internal classes exposed in public packages#22758

Draft
unknowntpo wants to merge 2 commits into
apache:trunkfrom
unknowntpo:kip-1320-poc
Draft

KIP-1320 (PoC): deprecation approach for internal classes exposed in public packages#22758
unknowntpo wants to merge 2 commits into
apache:trunkfrom
unknowntpo:kip-1320-poc

Conversation

@unknowntpo

@unknowntpo unknowntpo commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Draft / proof-of-concept for KIP-1320. Not meant to be merged as-is.
It shows the KIP's deprecation approach on a couple of small classes. It
is only a demonstration — the choice for any specific class is left to
the maintainers.

The idea

KIP-1320 deprecates classes that were never public API but sit in a
public package, so third parties can import them. Deprecating them gives
those users a compile-time warning before support ends at 5.0.0. There
are three cases; the first two involve code and each has an example
below:

1. Move to an internals package — ByteBufferInputStream

  • ByteBufferInputStream is an internal-only utility, so it is moved to
    the internals package where it belongs
    (org.apache.kafka.common.utils.internals.ByteBufferInputStream);
  • the old public class becomes a thin @Deprecated(since = "4.4", forRemoval = true) wrapper that extends the internal class, so no
    code is copied. Existing new ByteBufferInputStream(...) still works
    (source- and binary-compatible) and now shows a removal warning;
  • Kafka's own callers just import the internal class instead.
    forRemoval = true is correct here, because the public wrapper is
    really removed in 5.0.0.

2. Deprecate in place — ProducerIdAndEpoch

  • some classes do not need to be moved to an internals package.
    ProducerIdAndEpoch is used here only as an example of this case; it is
    simply marked @Deprecated(since = "4.4") where it already is;
  • the callers keep using it and add @SuppressWarnings("deprecation"),
    since there is no internal class to switch to. In the large public
    classes (KafkaProducer, KafkaAdminClient) the annotation is put only
    on the methods that use it; class level is used only where a class uses
    it in many places (for example TransactionManager);
  • in 5.0.0 the @Deprecated (and the @SuppressWarnings on the
    callers) is removed. The class stays for Kafka's internal use, and from
    5.0.0 the policy already treats it as unsupported, so the warning is no
    longer needed.

3. Policy only, no @Deprecated -- for rarely-used classes

If almost no one imports a class, a warning helps no one, and adding
@Deprecated still costs the caller changes shown above -- so it is not
worth it. These classes are simply left to the policy (unsupported from
5.0.0), with no code change at all. For example, LoggingSignalHandler
has only about 5 external imports on GitHub, so it would get nothing but
the policy. There is no diff for this case, which is the point.

Which approach fits which class is up to the maintainers; this PoC shows
that the two code cases compile and work.

How it was checked

  • ./gradlew compileJava (all modules, -Werror) — passes
  • checkstyleMain, spotlessCheck — pass
  • If you change one ByteBufferInputStream caller back to the
    deprecated public class, the build fails with error: warnings found and -Werror specified. This shows the callers really do need to be handled.

Notes: for ByteBufferInputStream, the test callers are moved to the
internal class too, and its own test moves to the internals package.
(Test compilation does not use -Werror, so this was not strictly
required, but it keeps the code consistent.) Scala callers are not
affected because scalac runs with -deprecation:false.

Links

@github-actions github-actions Bot added triage PRs from the community streams clients labels Jul 5, 2026
@unknowntpo unknowntpo changed the title KIP-1320 (PoC): move ByteBufferInputStream to internals behind a deprecated shim KIP-1320 (PoC): deprecation approach for internal classes exposed in public packages Jul 5, 2026
@unknowntpo unknowntpo force-pushed the kip-1320-poc branch 3 times, most recently from 2c1eafd to c3f6796 Compare July 5, 2026 04:08
…ecated shim

common.utils.ByteBufferInputStream (never public API, but importable) is moved to
common.utils.internals.ByteBufferInputStream, and the public class becomes a
@deprecated(since="4.4", forRemoval=true) wrapper that extends the internal class
(no copied code). Main-source and test callers switch to the internal class, and
the class's test moves to the internals package. Main compiles clean under
-Xlint:all -Werror.

Discussion: https://lists.apache.org/thread/5hf11khclhngftp297hhvwc23j5bcx28
…ernals move

A class with only a few internal callers can be deprecated in place instead of
moved. common.utils.ProducerIdAndEpoch is marked plain @deprecated(since="4.4"),
not forRemoval, since it stays for Kafka's internal use and its removal is not
committed. Its 9 main-source callers add @SuppressWarnings("deprecation"), scoped
to the methods in the large public classes (KafkaProducer, KafkaAdminClient) and
at class level where usage is in many places (TransactionManager).

Discussion: https://lists.apache.org/thread/5hf11khclhngftp297hhvwc23j5bcx28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant