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 >>>>>>>>>>> >>>>>>>>>> >>>>>>>> >>>>>>>> >>>>>> >>>>>> >>>> >>>> >> >>