KAFKA-14012: Add warning to closeQuietly documentation about method references of null objects#12321
Conversation
… passed a lambda object
C0urante
left a comment
There was a problem hiding this comment.
I think there's a better way to go about this. The general issue we're trying to address is that accessing null references can throw NPEs; there's nothing very special about the case of method references and Utils::closeQuietly.
If we were to follow the logic in this PR as-is, we'd have to add if (thing != null) checks around every method invocation on thing, which would have to happen here, here, here, here, etc.
A less-verbose approach that'd be just as safe is to rely on guarantees we can get at construction time for these objects:
- The
configLogfield ofKafkaConfigBackingStoreis declared final and initialized in the constructor; we can easily verify that it will never be null - The
offsetStorefield ofAbstractWorkerSourceTaskis also declared final, and accepted as a constructor parameter. Since we never pass innullas theoffsetStoreparameter to the constructor for this class, we can add a call toObjects::requireNonNullin the constructor that won't break any existing code, and will obviate the need for null checks in other parts of the class
The reason we have a special case for this in WorkerConnector is that its offsetStore can be null, since that class is used for both source connectors (which an offset store is brought up for) and sink connectors (which no offset store is brought up for).
Thanks for the detailed explanation Chris! I think this suggestion of yours is a lot neater. Also, I realised that on similar lines, I don't need a null check for |
C0urante
left a comment
There was a problem hiding this comment.
LGTM! (With some non-blocker suggestions)
I wonder if there are some higher-level fixes we might also adopt that would make NPEs from method references harder to write. Some ideas that come to mind:
- Stop using method references where possible and start actually implementing the
AutoCloseableinterface (this seems reasonable for the*BackingStoreinterfaces given that they already have stop() methods that behave closely toAutoCloseable::close, for example). - Add a new variant to
Utils::closeQuietlythat accepts a possibly-null object and some kind of consumer that can be applied to that object if it's non-null that will close it; I'm imagining calling it would look something likecloseQuietly(producer, p -> p.close(duration), "source task producer");instead of the existing logic for closing a source task's producer, orcloseQuietly(offsetStore, OffsetBackingStore::stop, "offset backing store")instead of the existing logic for stopping a source task's offset store.
connect/runtime/src/main/java/org/apache/kafka/connect/runtime/AbstractWorkerSourceTask.java
Outdated
Show resolved
Hide resolved
Thanks. I was actually thinking about something like option #2 but then when I saw, there are changes needed at only a couple of places, I didn't proceed. Do you think we can have a follow up ticket for this? |
Yes, this can definitely be a follow-up. Although given how small this PR has become, it'd be fine to add on here as well. FWIW, the more I think about it the more appealing option 1 seems. The variant I proposed for Edit: Ugh, no, that doesn't address the case of producers and other objects that have more sophisticated cleanup methods that require parameters. Hmm... I think at the very least we might want to put a warning note in the Javadocs for the existing |
Thanks @C0urante .. yeah that makes sense.. I added the javadocs to the closeQuietly and it's variants. Plz review. |
|
@showuon , could you plz review these changes whenever you get the chance? |
|
@showuon could you plz review/merge this? Thanks! |
|
@C0urante i believe now even you might be able to merge this :D |
|
@vamossagar12 LGTM! And just FYI, I've modified the title of the PR to more-accurately reflect the state it's in now, which should make the commit history clearer. |
|
Thanks @C0urante ! |
…(5 August 2022) Version related conflicts: * Jenkinsfile * gradle.properties * streams/quickstart/java/pom.xml * streams/quickstart/java/src/main/resources/archetype-resources/pom.xml * streams/quickstart/pom.xml * tests/kafkatest/__init__.py * tests/kafkatest/version.py * commit 'add7cd85baa61cd0e1430': (66 commits) KAFKA-14136 Generate ConfigRecord for brokers even if the value is unchanged (apache#12483) HOTFIX / KAFKA-14130: Reduce RackAwarenesssTest to unit Test (apache#12476) MINOR: Remove ARM/PowerPC builds from Jenkinsfile (apache#12380) KAFKA-14111 Fix sensitive dynamic broker configs in KRaft (apache#12455) KAFKA-13877: Fix flakiness in RackAwarenessIntegrationTest (apache#12468) KAFKA-14129: KRaft must check manual assignments for createTopics are contiguous (apache#12467) KAFKA-13546: Do not fail connector validation if default topic creation group is explicitly specified (apache#11615) KAFKA-14122: Fix flaky test DynamicBrokerReconfigurationTest#testKeyStoreAlter (apache#12452) MINOR; Use right enum value for broker registration change (apache#12236) MINOR; Synchronize access to snapshots' TreeMap (apache#12464) MINOR; Bump trunk to 3.4.0-SNAPSHOT (apache#12463) MINOR: Stop logging 404s at ERROR level in Connect KAFKA-14095: Improve handling of sync offset failures in MirrorMaker (apache#12432) Minor: enable index for emit final sliding window (apache#12461) MINOR: convert some more junit tests to support KRaft (apache#12456) KAFKA-14108: Ensure both JUnit 4 and JUnit 5 tests run (apache#12441) MINOR: Remove code of removed metric (apache#12453) MINOR: Update comment on verifyTaskGenerationAndOwnership method in DistributedHerder KAFKA-14012: Add warning to closeQuietly documentation about method references of null objects (apache#12321) MINOR: Fix static mock usage in ThreadMetricsTest (apache#12454) ...
Utils.closeQuietly method accepts
AutoCloseableobject, and close it and sometimes, method references of null objects are passed to it which causes npes. This PR fixes it..