hi all,

If we want to avoid both "large changes" and "unnecessary public APIs", another 
option is to introduce a nested @InterfaceAudience.Private class inside the 
@InterfaceAudience.Public class. I previously shared an example of this 
approach here: https://github.com/apache/kafka/pull/21337#discussion_r3574009798

The advantages are straightforward, and the only downside is that users must 
understand what the word "Internal" means. Fortunately, I have high confidence 
in most developers' vocabulary :)

Best,
Chia-Ping

On 2026/08/01 23:04:02 "Matthias J. Sax" wrote:
> Can't we rewrite the package-private constructor to create `TestMetrics` 
> object instead of `Metrics`? Or instead of passing in `Time`, we pass in 
> the `Metrics` object itself, and we let the test-code create `new 
> TestMetrics`?
> 
> 
> -Matthias
> 
> On 7/31/26 2:48 PM, Siddhartha Devineni wrote:
> > Hi Matthias,
> > 
> > Quick clarification: since KafkaProducer, KafkaAdminClient, etc. are in
> > different packages than Metrics, wouldn't they lose access entirely once
> > the constructor is package-private in 5.0, regardless of whether they pass
> > Time.SYSTEM or a custom Time?
> > 
> > Looking at KafkaProducer specifically:
> > One of its public constructors already hardcodes Time.SYSTEM, but the
> > package-private "visible for testing" KafkaProducer constructor (used by
> > tests to inject MockTime) still calls new Metrics(metricConfig, reporters,
> > time, metricsContext): a cross-package call into
> > org.apache.kafka.common.metrics.
> > 
> > That call would break once Metrics' constructor becomes package-private,
> > since KafkaProducer lives in org.apache.kafka.clients.producer.
> > 
> > Would a sister class (like TestMetrics) be needed here too, or is there a
> > different approach in mind for these "visible for testing"
> > constructors/methods that sit in other packages?
> > 
> > Thanks,
> > Siddhartha
> > 
> > On Fri, Jul 31, 2026 at 7:42 PM Matthias J. Sax <[email protected]> wrote:
> > 
> >> I am not totally sure I understand the "plash radius" problem and claim
> >> of a required huge code change?
> >>
> >> For `Metrics` for example, we currently pass in a `Time` object in unit
> >> tests. So I think we can make the deprecated constructors
> >> package-private in 5.0, effectively removing them from the public API.
> >> We create a "sister class" `TestMetrics extends Metrics` (same package)
> >> in a test module, and add a public constructor accepting the now
> >> internal `Time` as parameter, allowing all tests to create `new
> >> TestMetrics` object.
> >>
> >> This should not be a huge code change, and mostly only touching test
> >> code? -- We can also POC this now to really judge how large such a PR
> >> would get (happy to do it myself), and we could even merge it as part of
> >> the KIP, do the 5.0 change is prepared and reduced to only removing the
> >> `public` modifier on all deprecated constructors.
> >>
> >>
> >> Thoughts?
> >>
> >>
> >> -Matthias
> >>
> >>
> >> On 7/29/26 10:02 AM, Siddhartha Devineni wrote:
> >>> Hello all,
> >>>
> >>> I have updated the KIP.
> >>> Please have a look:
> >>>
> >> https://cwiki.apache.org/confluence/spaces/KAFKA/pages/406623925/KIP-1311+Extract+minimal+public+Time+interface+from+internal+Time+API
> >>>
> >>> Thanks,
> >>> Siddhartha
> >>>
> >>> On Tue, Jul 21, 2026 at 11:32 AM Siddhartha Devineni <
> >>> [email protected]> wrote:
> >>>
> >>>> Sure and i will let you all know when it's done
> >>>>
> >>>> On Tue, 21 Jul 2026, 10:13 Chia-Ping Tsai, <[email protected]> wrote:
> >>>>
> >>>>> Yes, Sean’s approach LGTM
> >>>>>
> >>>>> Would you mind updating the KIP?
> >>>>>
> >>>>> Thanks!
> >>>>>
> >>>>>> Siddhartha Devineni <[email protected]> 於 2026年7月21日
> >>>>> 下午3:21 寫道:
> >>>>>>
> >>>>>> Hi Chia-Ping,
> >>>>>>
> >>>>>> You are right that @SuppressWarnings is just a temporary workaround.
> >>>>>> The fundamental issue remains: in version 5.0, when constructors
> >> become
> >>>>>> package-private, internal Kafka code in other packages (KafkaProducer,
> >>>>>> KafkaAdminClient, etc.) will lose access.
> >>>>>>
> >>>>>> Given these constraints, Sean's minimal public Time interface seems to
> >>>>> be
> >>>>>> the cleanest solution.
> >>>>>>
> >>>>>> Thanks.
> >>>>>>
> >>>>>>> On Tue, Jul 21, 2026 at 8:25 AM Chia-Ping Tsai <[email protected]>
> >>>>> wrote:
> >>>>>>>
> >>>>>>> hi Siddhartha
> >>>>>>>
> >>>>>>> I might be misunderstanding the approach of this PR. The
> >>>>>>> @SuppressWarnings("deprecation") annotation is just a temporary
> >>>>> workaround
> >>>>>>> for now, right? We will eventually face the same issue in version
> >> 5.0:
> >>>>> how
> >>>>>>> to create a Metrics instance with a specific Time object from another
> >>>>>>> package.
> >>>>>>>
> >>>>>>> Best,
> >>>>>>> Chia-Ping
> >>>>>>>
> >>>>>>>> On 2026/07/20 21:34:15 Siddhartha Devineni wrote:
> >>>>>>>> Hi Chia-Ping and Sean,
> >>>>>>>>
> >>>>>>>> To clarify the earlier discussion, after further investigation,
> >>>>> "Metrics"
> >>>>>>>> doesn't call any "Time" methods directly, rather it just stores and
> >>>>>>> passes
> >>>>>>>> it to internal components (this.time = time on line 174).
> >>>>>>>>
> >>>>>>>> This means no officially public Javadoc class actually needs to call
> >>>>> any
> >>>>>>>> "Time" methods.
> >>>>>>>>
> >>>>>>>> So, we could simply:
> >>>>>>>> 1. Deprecate Time-accepting constructors in "Metrics" and
> >>>>> "KafkaStreams"
> >>>>>>>> 2. Keep "Time" as internal API
> >>>>>>>> 3. No new public interface needed
> >>>>>>>>
> >>>>>>>> I have already created a PR implementing this approach after
> >>>>>>>> withdrawing the KIP
> >>>>>>>>
> >>>>>>>> https://github.com/apache/kafka/pull/22689
> >>>>>>>>
> >>>>>>>> WDYT?
> >>>>>>>>
> >>>>>>>> Thanks and Best regards,
> >>>>>>>> Siddhartha
> >>>>>>>>
> >>>>>>>> On Mon, Jul 20, 2026 at 8:02 PM Chia-Ping Tsai <[email protected]
> >>>
> >>>>>>> wrote:
> >>>>>>>>
> >>>>>>>>> hi Alieh
> >>>>>>>>>
> >>>>>>>>> We could keep discussing on this mail thread.
> >>>>>>>>>
> >>>>>>>>> The solution provided by Sean is pretty good. Except for
> >>>>> KafkaStreams,
> >>>>>>> the
> >>>>>>>>> others only use the  `milliseconds` so we could have a new simple
> >>>>>>> interface
> >>>>>>>>> Time, which could be located at org.apache.kafka.common, to replace
> >>>>>>> origin
> >>>>>>>>> Time-accepting constructor
> >>>>>>>>>
> >>>>>>>>> Best,
> >>>>>>>>> Chia-Ping
> >>>>>>>>>
> >>>>>>>>> On 2026/07/20 14:27:00 Alieh Saeedi via dev wrote:
> >>>>>>>>>> Hi
> >>>>>>>>>>
> >>>>>>>>>> Why is the KIP marked as withdrawn if the discussion is still
> >>>>>>> ongoing in
> >>>>>>>>>> the same thread?
> >>>>>>>>>>
> >>>>>>>>>> -Alieh
> >>>>>>>>>>
> >>>>>>>>>> On Mon, Jul 20, 2026 at 3:31 PM Sean Quah via dev <
> >>>>>>> [email protected]>
> >>>>>>>>>> wrote:
> >>>>>>>>>>
> >>>>>>>>>>> Hi,
> >>>>>>>>>>>
> >>>>>>>>>>> I was hoping we could avoid making Time public. Failing that, is
> >> it
> >>>>>>>>>>> possible to reduce the public API surface further? I looked at
> >>>>>>> Metrics
> >>>>>>>>>>> before and it only wanted the wall clock (milliseconds()).
> >> Perhaps
> >>>>>>>>>>> the other constructors are the same?
> >>>>>>>>>>> We could perhaps have a very simple public Time interface only
> >>>>>>> exposing
> >>>>>>>>>>> milliseconds (effectively a wall clock interface) and an internal
> >>>>>>> Time
> >>>>>>>>>>> interface which extends it with other methods.
> >>>>>>>>>>>
> >>>>>>>>>>> Thanks,
> >>>>>>>>>>> Sean
> >>>>>>>>>>>
> >>>>>>>>>>> On Mon, Jul 20, 2026 at 8:51 AM Chia-Ping Tsai <
> >>>>>>> [email protected]>
> >>>>>>>>>>> wrote:
> >>>>>>>>>>>
> >>>>>>>>>>>> hi all,
> >>>>>>>>>>>>
> >>>>>>>>>>>> I re-read the constructors, and I think deprecating the
> >>>>>>>>> time-accepting
> >>>>>>>>>>>> constructors will introduce huge changes to the codebase.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Maybe we could just make Time public with a few methods, such as
> >>>>>>>>>>>> milliseconds, nanoseconds, and sleep. Since Timer is not public,
> >>>>>>> we
> >>>>>>>>> could
> >>>>>>>>>>>> add a helper method to Timer, like Timer.create(Time, ...), to
> >>>>>>>>> replace
> >>>>>>>>>>>> Time#timer().
> >>>>>>>>>>>>
> >>>>>>>>>>>> WDYT?
> >>>>>>>>>>>>
> >>>>>>>>>>>> On 2026/04/23 20:57:19 Siddhartha Devineni wrote:
> >>>>>>>>>>>>> Hi Chia-Ping, Kirk and Matthias,
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> @Chia-Ping: You were right - after investigating, Time doesn't
> >>>>>>>>> need to
> >>>>>>>>>>> be
> >>>>>>>>>>>>> public.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> @Kirk: You are right - the OAuth examples are instantiated via
> >>>>>>>>>>>> reflection,
> >>>>>>>>>>>>> not direct user code.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> @Matthias: Good points. I investigated whether Metrics can be
> >>>>>>>>> changed
> >>>>>>>>>>> to
> >>>>>>>>>>>>> not expose Time.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Findings:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> - new Metrics() - users call this (internally uses Time.SYSTEM)
> >>>>>>>>>>>>> - new Metrics(Time time) and other variants - only called by
> >>>>>>>>> internal
> >>>>>>>>>>>> Kafka
> >>>>>>>>>>>>> code (KafkaProducer, KafkaAdminClient, etc) and tests
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Proposed approach:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> - Withdraw KIP-1311 (Make Time public)
> >>>>>>>>>>>>> - Create JIRA: "Deprecate Time-accepting constructors"
> >>>>>>>>>>>>> - Deprecate Time constructors in both KafkaStreams and Metrics:
> >>>>>>>>>>>>>       - KafkaStreams(Topology, Properties, Time)
> >>>>>>>>>>>>>       - KafkaStreams(Topology, StreamsConfig, Time)
> >>>>>>>>>>>>>       - KafkaStreams(Topology, Properties, KafkaClientSupplier,
> >>>>>>>>> Time)
> >>>>>>>>>>>>>       - Metrics(Time)
> >>>>>>>>>>>>>       - Metrics(MetricConfig, Time)
> >>>>>>>>>>>>>       - Metrics(MetricConfig, List<MetricsReporter>, Time)
> >>>>>>>>>>>>>       - (and other Metrics variants accepting Time)
> >>>>>>>>>>>>> - In version 5.0, make these constructors package-private
> >>>>>>>>>>>>> - Internal Kafka code continues using them
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Result: Time remains internal.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Does this approach work? If so, I'll withdraw KIP-1311 and
> >>>>>>> create
> >>>>>>>>> the
> >>>>>>>>>>>> JIRA.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Thank you,
> >>>>>>>>>>>>> Siddhartha
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> On Tue, Apr 21, 2026 at 5:22 AM Matthias J. Sax <
> >>>>>>> [email protected]>
> >>>>>>>>>>>> wrote:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>> Thanks for the KIP. I am not sure if I understand why
> >>>>>>>>>>>> `KafkaStreamsMock`
> >>>>>>>>>>>>>> would be anything public?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Also, why would we put it into some new `...test...`
> >>>>>>> package? If
> >>>>>>>>> we
> >>>>>>>>>>>>>> change the package, we need to have `protected` access,
> >>>>>>> which is
> >>>>>>>>>>>> already
> >>>>>>>>>>>>>> "semi-public"...
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> If we want to keep `Time` internal, we would eventually make
> >>>>>>> the
> >>>>>>>>>>>>>> constructors that are marked deprecated, package-private,
> >>>>>>> what
> >>>>>>>>> allows
> >>>>>>>>>>>> us
> >>>>>>>>>>>>>> to add `org.apache.kafka.streams.KafkaStreamsMock` (same
> >>>>>>> package
> >>>>>>>>>>> name,
> >>>>>>>>>>>>>> but int `test/` module) to still use these constructors, and
> >>>>>>> the
> >>>>>>>>>>>>>> corresponding unit test would use the new mock-factory
> >>>>>>> instead of
> >>>>>>>>>>>>>> calling `new`?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> For this case, the KIP does not need to mention anything
> >>>>>>> about
> >>>>>>>>>>>>>> `KafkaStreamsMock` as it's an helper in our `test/` module
> >>>>>>> only,
> >>>>>>>>> but
> >>>>>>>>>>>> not
> >>>>>>>>>>>>>> public API. -- If we want, we can still mention this plan on
> >>>>>>> the
> >>>>>>>>> KIP,
> >>>>>>>>>>>>>> but atm the KIP is written in a way as if `KafkaStreamsMock`
> >>>>>>>>> would
> >>>>>>>>>>>>>> become public API, but to my understanding it should be an
> >>>>>>>>>>> impl/testing
> >>>>>>>>>>>>>> details only?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Or did I misunderstand something?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> Also wondering, if we could also change `Metrics` in a way,
> >>>>>>> that
> >>>>>>>>> we
> >>>>>>>>>>>>>> would not need to make `Time` public to begin with?
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> -Matthias
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>> On 4/20/26 4:53 PM, Kirk True wrote:
> >>>>>>>>>>>>>>> Hi Siddhartha,
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> The OAuth examples use Time in their constructors for unit
> >>>>>>>>> tests.
> >>>>>>>>>>>>>> They're not intended to be instantiated by any user code
> >>>>>>> since
> >>>>>>>>>>> they're
> >>>>>>>>>>>> in
> >>>>>>>>>>>>>> an internals package.
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> Thanks,
> >>>>>>>>>>>>>>> Kirk
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>> On Wed, Apr 15, 2026, at 8:52 AM, Siddhartha Devineni
> >>>>>>> wrote:
> >>>>>>>>>>>>>>>> Hi Chia-Ping,
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> Sorry that i didn't mention the following examples in the
> >>>>>>> KIP
> >>>>>>>>>>>> earlier.
> >>>>>>>>>>>>>>>> Now, I have updated the KIP with the following public
> >>>>>>> packages
> >>>>>>>>>>>> examples,
> >>>>>>>>>>>>>>>> where "Time" is exposed in the public constructors:
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> // couple of examples from multiple
> >>>>>>>>>>>>>>>> "org.apache.kafka.common.metrics.Metrics.java"
> >>>>>>> constructors
> >>>>>>>>>>>>>>>> public Metrics(Time time) {}
> >>>>>>>>>>>>>>>> public Metrics(MetricConfig defaultConfig, Time time) {}
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> // in the public package
> >>>>>>>>>>>> "org.apache.kafka.common.security.oauthbearer"
> >>>>>>>>>>>>>>>> public JwtBearerJwtRetriever(Time time) {}
> >>>>>>>>>>>>>>>> public ClientCredentialsJwtRetriever(Time time) {}
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> Now, it should be clear.
> >>>>>>>>>>>>>>>> Thanks for your time.
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> Best regards,
> >>>>>>>>>>>>>>>> Siddhartha
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>> On Tue, Apr 14, 2026 at 11:14 AM Chia-Ping Tsai <
> >>>>>>>>>>> [email protected]
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>> wrote:
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> hi Siddhartha
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Thanks for this KIP.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> What is the exact benefit of exposing Time as a public
> >>>>>>> API?
> >>>>>>>>> Since
> >>>>>>>>>>>> this
> >>>>>>>>>>>>>> KIP
> >>>>>>>>>>>>>>>>> proposes deprecating KafkaStreams(Topology, Properties,
> >>>>>>>>> Time), it
> >>>>>>>>>>>> seems
> >>>>>>>>>>>>>>>>> there are no public interfaces relying on it anymore.
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Thus, it should be fine to just keep Time as an internal
> >>>>>>> API,
> >>>>>>>>>>>> right?
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Best,
> >>>>>>>>>>>>>>>>> Chia-Ping
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>> Siddhartha Devineni <[email protected]> 於
> >>>>>>>>>>> 2026年4月7日週二
> >>>>>>>>>>>>>>>>> 下午2:19寫道:
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> Apologies, as I forgot to add the link to the KIP:
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>
> >>>>>>>
> >>>>>
> >> https://urldefense.com/v3/__https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=406623925__;!!Ayb5sqE7!o-ar2zzpALvIzp5wF7s2E77bUw9C8CxXLU1JxqxsiiliVfUFzl_M8gIOcFoy3T1nFx5L78W0vA8d7XV_enMH$
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>> On Tue, Apr 7, 2026 at 9:13 AM Siddhartha Devineni <
> >>>>>>>>>>>>>>>>>> [email protected]> wrote:
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> Hello everyone,
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> I would like to start a discussion on [DISCUSS]
> >>>>>>> KIP-1311:
> >>>>>>>>> Make
> >>>>>>>>>>>>>>>>> Time/Timer
> >>>>>>>>>>>>>>>>>>> public API.
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> Following KIP-1247 (Make Bytes part of public API), the
> >>>>>>>>> Time
> >>>>>>>>>>>>>> interface
> >>>>>>>>>>>>>>>>>> and
> >>>>>>>>>>>>>>>>>>> Timer class are the next candidates from
> >>>>>>>>>>>>>>>>> "org.apache.kafka.common.utils"
> >>>>>>>>>>>>>>>>>> to
> >>>>>>>>>>>>>>>>>>> be made officially public. Time is currently exposed
> >>>>>>>>> through
> >>>>>>>>>>>> public
> >>>>>>>>>>>>>>>>> APIs
> >>>>>>>>>>>>>>>>>>> (e.g., in clients, KafkaStreams constructors, etc) but
> >>>>>>> not
> >>>>>>>>>>>> officially
> >>>>>>>>>>>>>>>>>>> designated as a public API.
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> An earlier version of this KIP explored splitting Time
> >>>>>>> into
> >>>>>>>>>>>> focused
> >>>>>>>>>>>>>>>>>>> interfaces (Clock, MonotonicClock, etc.), but this
> >>>>>>> would
> >>>>>>>>>>> require
> >>>>>>>>>>>>>>>>>> rewriting
> >>>>>>>>>>>>>>>>>>> thousands of method signatures across the Kafka
> >>>>>>> codebase.
> >>>>>>>>> The
> >>>>>>>>>>>> simpler
> >>>>>>>>>>>>>>>>>>> approach of making Time public as-is seems more
> >>>>>>>>> appropriate to
> >>>>>>>>>>>> avoid
> >>>>>>>>>>>>>>>>>>> breaking changes.
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> Looking forward to your feedback.
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>> Thank you,
> >>>>>>>>>>>>>>>>>>> Siddhartha
> >>>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>
> >>>>
> >>>
> >>
> >>
> > 
> 
> 

Reply via email to