Hello chia, Thanks for the reply.
chia05: I have updated the KIP to change the default values of task.assigned.groups and task.assigned.partitions from null to NO_DEFAULT_VALUE. chia06: I have also updated the KIP based on your feedback. Best Regards, Jiunn-Yang > Chia-Ping Tsai <chia7...@gmail.com> 於 2025年8月6日 凌晨12:54 寫道: > > hi Jiunn-Yang > > chia05: > > `task.assigned.groups` and `task.assigned.partitions` should not have > default value, right? > > chia06: > > `new HashSet<>(values).size()` -> `Set.copyOf(values).size()` > > Best, > Chia-Ping > > Jun Rao <j...@confluent.io.invalid> 於 2025年8月5日 週二 下午11:39寫道: > >> Hi, Jiunn-Yang, >> >> Thanks for the reply and your patience. The KIP looks good to me now. >> >> Hi, Luke, Mickael, >> >> Could you take a look at the KIP again and see if it makes sense to you? >> >> Thanks, >> >> Jun >> >> On Tue, Aug 5, 2025 at 3:04 AM 黃竣陽 <s7133...@gmail.com> wrote: >> >>> Hello Jun, >>> >>> Thanks for the reply, >>> >>> JR46: I have clarified the behavior for null and empty values, so users >>> can >>> understand the reasoning behind disallowing empty lists. >>> >>> JR48: I've updated the KIP accordingly. >>> >>> Best Regards, >>> Jiunn-Yang >>> >>>> Jun Rao <j...@confluent.io.INVALID> 於 2025年8月5日 凌晨12:45 寫道: >>>> >>>> Hi, Jiunn-Yang, >>>> >>>> Thanks for the reply. >>>> >>>> JR46. "Currently, if plugin.path is set to an empty list, no >>> user-specified >>>> plugin locations are processed, but plugins from the parent classloader >>> are >>>> still loaded." Could you add why the current behavior is bad for the >>> users? >>>> >>>> JR48. If we want to preserve the current behavior, we should remove the >>>> following validation, right? >>>> if (validStrings.length == 0) { >>>> throw new IllegalArgumentException("Valid strings list >> cannot >>>> be empty for in validator"); >>>> >>>> Jun >>>> >>>> On Fri, Aug 1, 2025 at 6:47 PM 黃竣陽 <s7133...@gmail.com> wrote: >>>> >>>>> Hello Jun, >>>>> >>>>> Thanks for the reply. >>>>> >>>>> JR42, JR45, JR46, JR47: I have updated the KIP. >>>>> >>>>> JR43: If bootstrap.servers is empty for these configurations, >>>>> it will fail when creating the AdminClient. I have updated the KIP to >>>>> reflect this behavior. >>>>> >>>>> JR44: Thanks for pointing this out. Kafka will indeed fail at the >>> storage >>>>> format phase >>>>> if the configuration is invalid. I have updated the KIP accordingly. >>>>> >>>>> JR48: The current in() method allows empty lists by default, so I >>> believe >>>>> setting isEmptyAllowed to true >>>>> better preserves the original behavior. Therefore, I prefer not to >>> change >>>>> this default. >>>>> >>>>> Best Regards, >>>>> Jiunn-Yang >>>>> >>>>>> Jun Rao <j...@confluent.io.INVALID> 於 2025年8月2日 凌晨2:38 寫道: >>>>>> >>>>>> Hi, Jiunn-Yang, >>>>>> >>>>>> Thanks for the reply. A few more comments. >>>>>> >>>>>> JR42. [6] [7] are not needed since currently an empty list already >>> causes >>>>>> an exception. >>>>>> >>>>>> JR43. Could you document the current behavior when bootstrap.servers >> is >>>>>> empty in MirrorClientConfig and WorkerConfig? >>>>>> >>>>>> JR44. [12] seems incorrect. I set log.dir, but left log.dirs empty >> and >>>>> got >>>>>> the following. >>>>>> bin/kafka-storage.sh format --standalone -t $KAFKA_CLUSTER_ID -c >>>>>> config/server.properties >>>>>> Exception in thread "main" java.lang.IllegalArgumentException: >>>>> requirement >>>>>> failed: At least one log directory must be defined via log.dirs or >>>>> log.dir. >>>>>> >>>>>> bin/kafka-server-start.sh config/server.properties >>>>>> [2025-08-01 11:31:20,097] INFO Registered >>>>>> `kafka:type=kafka.Log4jController` MBean >>>>>> (kafka.utils.Log4jControllerRegistration$) >>>>>> [2025-08-01 11:31:20,238] ERROR Exiting Kafka due to fatal exception >>>>>> (kafka.Kafka$) >>>>>> java.lang.IllegalArgumentException: requirement failed: At least one >>> log >>>>>> directory must be defined via log.dirs or log.dir. >>>>>> >>>>>> JR45. Could you group all configs for WorkerConfig together? >>>>>> >>>>>> JR46. plugin.path: We have the following code. So, currently, it >> seems >>>>> that >>>>>> an empty list is allowed for plugin.path and we treat it by adding >> the >>>>>> parent path of the classloader. It would be useful to justify why >>>>>> disallowing empty is better for the users. >>>>>> >>>>>> public static Set<PluginSource> pluginSources(Set<Path> >>>>>> pluginLocations, ClassLoader classLoader, PluginClassLoaderFactory >>>>> factory) >>>>>> { >>>>>> Set<PluginSource> pluginSources = new LinkedHashSet<>(); >>>>>> for (Path pluginLocation : pluginLocations) { >>>>>> try { >>>>>> pluginSources.add(isolatedPluginSource(pluginLocation, >>>>>> classLoader, factory)); >>>>>> } catch (InvalidPathException | MalformedURLException e) { >>>>>> log.error("Invalid path in plugin path: {}. Ignoring.", >>>>>> pluginLocation, e); >>>>>> } catch (IOException e) { >>>>>> log.error("Could not get listing for plugin path: {}. >>>>>> Ignoring.", pluginLocation, e); >>>>>> } >>>>>> } >>>>>> >>> pluginSources.add(classpathPluginSource(classLoader.getParent())); >>>>>> return pluginSources; >>>>>> } >>>>>> >>>>>> JR47. typo in "Should not allow setting validStrings is empty" >>>>>> >>>>>> JR48. We should pass in isEmptyAllowed as false in the code below, >>> right? >>>>>> public static ValidList in(String... validStrings) { >>>>>> if (validStrings.length == 0) { >>>>>> throw new IllegalArgumentException("Valid strings list >> cannot >>>>>> be empty for in validator"); >>>>>> } >>>>>> return new ValidList(List.of(validStrings), true, false); >>>>>> } >>>>>> >>>>>> Jun >>>>>> >>>>>> On Tue, Jul 29, 2025 at 8:53 AM 黃竣陽 <s7133...@gmail.com> wrote: >>>>>> >>>>>>> Hello Jun, >>>>>>> >>>>>>> Sorry for the late reply, >>>>>>> >>>>>>> JR40, JR41: I have updated the KIP based on your comments. Please >>> take a >>>>>>> look. >>>>>>> >>>>>>> Best Regards, >>>>>>> Jiunn-Yang >>>>>>> >>>>>>>> Jun Rao <j...@confluent.io.INVALID> 於 2025年7月24日 凌晨2:56 寫道: >>>>>>>> >>>>>>>> Hi, Jiunn-Yang, >>>>>>>> >>>>>>>> Thanks for the reply. >>>>>>>> >>>>>>>> JR40. In the table, there are a few configs for which we now >> disallow >>>>>>> empty >>>>>>>> lists. It would be useful to document the current behavior for each >>> of >>>>>>> them >>>>>>>> more accurately. It seems that they should all lead to some bad >>>>> behavior. >>>>>>>> For example, if log.dirs is empty, it seems that we can't create >>>>> topics? >>>>>>>> If group.coordinator.rebalance.protocols is empty, the group >>> rebalance >>>>>>>> protocol will fail? >>>>>>>> >>>>>>>> JR41. It would be useful to clean up the "Compatibility, >> Deprecation, >>>>> and >>>>>>>> Migration Plan" section a bit. >>>>>>>> JR41.1 The migration plan has "Introduce a new properties >>>>> isEmptyAllowed >>>>>>> , >>>>>>>> isNullAllowed", which needs to be changed. >>>>>>>> JR41.2 It started with "For users who configure an empty list", but >>> not >>>>>>> all >>>>>>>> the bullet points are about empty lists. >>>>>>>> JR41.3 To me, it would be useful to summarize why the behavior >>> changes >>>>>>> are >>>>>>>> justified. We made 3 types of changes. (1) Disallow null. This is >> ok >>>>>>> since >>>>>>>> one can't really set a null value through a config file. (2) >> Disallow >>>>>>>> duplicates. This is ok since it's rare and confusing. (3) Disallow >>>>> empty. >>>>>>>> Ideally, we want to claim that for those cases, they all lead to >> some >>>>>>> other >>>>>>>> errors or had behavior currently. >>>>>>>> >>>>>>>> Jun >>>>>>>> >>>>>>>> On Wed, Jul 23, 2025 at 4:42 AM 黃竣陽 <s7133...@gmail.com> wrote: >>>>>>>> >>>>>>>>> Hello Jun, >>>>>>>>> >>>>>>>>> Thanks for the reply. >>>>>>>>> >>>>>>>>> JR34 ,JR36, JR39: I’ve updated the KIP to reflect these changes. >>>>>>>>> >>>>>>>>> JR38: I clarified the following configurations: >>>>>>>>> early.start.listeners: This config is optional and allows both >> null >>>>> and >>>>>>>>> empty lists. >>>>>>>>> log.dirs and plugin.path: These are also optional, but only allow >>>>>>>>> null—empty lists are not permitted. >>>>>>>>> >>>>>>>>> Best Regards, >>>>>>>>> Jiunn-Yang >>>>>>>>> >>>>>>>>>> Jun Rao <j...@confluent.io.INVALID> 於 2025年7月23日 凌晨2:28 寫道: >>>>>>>>>> >>>>>>>>>> Hi, Jiunn-Yang and Chia-Ping, >>>>>>>>>> >>>>>>>>>> Thanks for the reply. >>>>>>>>>> >>>>>>>>>> JR34. Sounds good. >>>>>>>>>> >>>>>>>>>> JR36. Could you document that the default value for >>>>>>>>>> sasl.oauthbearer.expected.audience and ssl.cipher.suites have >> been >>>>>>>>> changed? >>>>>>>>>> >>>>>>>>>> JR38. My concern wasn't quite addressed. "If the configuration is >>>>>>>>> optional, >>>>>>>>>> we will reject any duplicate values in the list." This implies >> that >>>>> if >>>>>>> a >>>>>>>>>> config is optional, we allow empty lists. However, for >> plugin.path, >>>>> we >>>>>>>>>> reject empty lists. >>>>>>>>>> >>>>>>>>>> JR39. We can remove the fields isEmptyAllowed and isNullAllowed >>> since >>>>>>>>> they >>>>>>>>>> are not public facing. >>>>>>>>>> >>>>>>>>>> Jun >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Tue, Jul 22, 2025 at 4:26 AM 黃竣陽 <s7133...@gmail.com> wrote: >>>>>>>>>> >>>>>>>>>>> Hello Jun, Chia, >>>>>>>>>>> >>>>>>>>>>> Thanks for the reply, >>>>>>>>>>> >>>>>>>>>>> JR36: I’ve updated the following configurations: >>>>>>>>>>> - sasl.oauthbearer.expected.audience >>>>>>>>>>> - ssl.cipher.suites >>>>>>>>>>> - ssl.enabled.protocols >>>>>>>>>>> These now allow both empty and non-empty lists. Since the >> default >>>>>>> values >>>>>>>>>>> of >>>>>>>>>>> sasl.oauthbearer.expected.audience and ssl.cipher.suites were >>>>>>> previously >>>>>>>>>>> null, >>>>>>>>>>> I’ve updated their defaults to List.of() for consistency. >>>>>>>>>>> >>>>>>>>>>> JR37: A ClassCastException does not occur in MirrorClientConfig >>> and >>>>> it >>>>>>>>>>> should be none. >>>>>>>>>>> I’ve updated this in the KIP. >>>>>>>>>>> >>>>>>>>>>> JR38 & JR40: I’ve added a note below the table to indicate which >>>>>>>>>>> configurations require special attention. >>>>>>>>>>> >>>>>>>>>>> JR39: Yes, these properties are package-private. >>>>>>>>>>> >>>>>>>>>>> Best Regards, >>>>>>>>>>> Jiunn-Yang >>>>>>>>>>> >>>>>>>>>>>> Chia-Ping Tsai <chia7...@gmail.com> 於 2025年7月22日 下午6:04 寫道: >>>>>>>>>>>> >>>>>>>>>>>> JR34. Hmm, it seems that the code in taskConfigs() could return >>> an >>>>>>>>> empty >>>>>>>>>>>> list for a task if knownSourceTopicPartitions is less than >>>>> maxTasks, >>>>>>>>>>>> Chia-Ping? >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Yes, `MirrorSourceConnector#taskConfigs` could return an empty >>>>> list, >>>>>>>>>>> which >>>>>>>>>>>> means no `MirrorSourceTask` can be created. >>>>>>>>>>>> >>>>>>>>>>>> By contrast, if any `MirrorSourceTask` is created, the configs >>> used >>>>>>> by >>>>>>>>>>>> `MirrorSourceTask` must contain `task.assigned.partitions` >> with a >>>>>>>>>>> non-empty >>>>>>>>>>>> value. >>>>>>>>>>>> >>>>>>>>>>>> Jun Rao <j...@confluent.io.invalid> 於 2025年7月22日 週二 上午5:14寫道: >>>>>>>>>>>> >>>>>>>>>>>>> Hi, Jiunn-Yang and Chia-Ping, >>>>>>>>>>>>> >>>>>>>>>>>>> Thanks for the reply. >>>>>>>>>>>>> >>>>>>>>>>>>> JR34. Hmm, it seems that the code in taskConfigs() could >> return >>> an >>>>>>>>> empty >>>>>>>>>>>>> list for a task if knownSourceTopicPartitions is less than >>>>> maxTasks, >>>>>>>>>>>>> Chia-Ping? >>>>>>>>>>>>> >>>>>>>>>>>>> JR36. Sounds good. Could you update the KIP? Also, should we >> do >>>>> the >>>>>>>>> same >>>>>>>>>>>>> for ssl.cipher.suites and sasl.oauthbearer.expected.audience? >>>>>>>>>>>>> >>>>>>>>>>>>> JR37. Is it true that MirrorClientConfig.bootstrap.servers >>> returns >>>>>>>>>>>>> ClassCastException for null? It seems that null could be >> casted >>> to >>>>>>> any >>>>>>>>>>>>> class. >>>>>>>>>>>>> >>>>>>>>>>>>> JR38. "If the configuration is optional, we will reject any >>>>>>> duplicate >>>>>>>>>>>>> values in the list." Could you clarify this? For example, >>>>>>> plugin.path >>>>>>>>> is >>>>>>>>>>>>> optional, but with a default value. We reject duplicates as >> well >>>>> as >>>>>>>>>>> empty >>>>>>>>>>>>> lists. >>>>>>>>>>>>> >>>>>>>>>>>>> JR39. isEmptyAllowed and isNullAllowed are not public fields, >>>>> right? >>>>>>>>>>> They >>>>>>>>>>>>> are only public in the anyNonDuplicateValues() method. >>>>>>>>>>>>> >>>>>>>>>>>>> JR40. It would be useful to mention that if cleanup.policy is >>>>> empty >>>>>>>>> and >>>>>>>>>>>>> remote.storage.enable is true, the local log segments will be >>>>>>> cleaned >>>>>>>>>>> based >>>>>>>>>>>>> on log.local.retention.bytes and log.local.retention.ms. >>>>>>>>>>>>> >>>>>>>>>>>>> Jun >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, Jul 18, 2025 at 9:52 AM Chia-Ping Tsai < >>>>> chia7...@gmail.com> >>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> JR34: For these two configurations, setting an empty list >>> feels >>>>> a >>>>>>>>> bit >>>>>>>>>>>>>>> unintuitive. If an empty list is >>>>>>>>>>>>>>> provided, the consumer will call the unsubscribe method, >> which >>>>>>>>> doesn't >>>>>>>>>>>>>>> seem appropriate given >>>>>>>>>>>>>>> the documentation states: "Topic-partitions assigned to this >>>>> task >>>>>>> to >>>>>>>>>>>>>>> replicate." >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> agreed. Additionally, the source code [0] shows that it is >> not >>>>>>>>> intended >>>>>>>>>>>>> to >>>>>>>>>>>>>> generate empty tps for the source task >>>>>>>>>>>>>> >>>>>>>>>>>>>> [0] >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>> >>>>>>> >>>>> >>> >> https://github.com/apache/kafka/blob/9b542b6ea21e84677a9292f250fc25f8b4162e6f/connect/mirror/src/main/java/org/apache/kafka/connect/mirror/MirrorSourceConnector.java#L202 >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>> >>>>>>> >>>>> >>>>> >>> >>> >>