[ 
https://issues.apache.org/jira/browse/KAFKA-20802?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Chia-Ping Tsai resolved KAFKA-20802.
------------------------------------
    Fix Version/s: 4.4.0
       Resolution: Fixed

> ClusterTestExtensions#afterEach throws NPE when a detected thread terminates 
> before the leak report is built
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: KAFKA-20802
>                 URL: https://issues.apache.org/jira/browse/KAFKA-20802
>             Project: Kafka
>          Issue Type: Bug
>            Reporter: Eric Chang
>            Assignee: Eric Chang
>            Priority: Major
>             Fix For: 4.4.0
>
>
> {{ClusterTestExtensions#afterEach}} builds the thread-leak error message with 
> {{t.getThreadGroup().getName()}}. {{Thread#getThreadGroup()}} returns null 
> after a thread has terminated.
> If a thread returned by {{DetectThreadLeak#newThreads()}} terminates between 
> the snapshot and message formatting, {{afterEach}} throws an NPE and fails 
> the test even though the thread is no longer a leak.
> h3. CI evidence
> * Full job: 
> https://github.com/apache/kafka/actions/runs/29228499012/job/86748625389
> * NPE in the JUnit test step: 
> https://github.com/apache/kafka/actions/runs/29228499012/job/86748625389#step:6:136310
> * Flaky-test report: 
> https://github.com/apache/kafka/actions/runs/29228499012/job/86748625389#step:10:1872
> * Affected test: 
> {{MetadataQuorumCommandTest.testDescribeQuorumStatusSuccessful [5]}}
> {code}
> java.lang.NullPointerException: Cannot invoke 
> "java.lang.ThreadGroup.getName()" because the return value of 
> "java.lang.Thread.getThreadGroup()" is null
>     at 
> org.apache.kafka.common.test.junit.ClusterTestExtensions.lambda$afterEach$2(ClusterTestExtensions.java:188)
> {code}
> h3. Reproduction
> A deterministic regression test can reproduce the same NPE by making 
> {{DetectThreadLeak#newThreads()}} return a thread that has already been 
> joined, then invoking the real {{afterEach}} path. The proposed logic passes 
> this regression test and continues to report live leaked threads.
> I also ran the actual affected test locally for 120 isolated cluster contexts 
> using Java 17, 4 forks, and retries disabled. All 120 passed, so the natural 
> timing window did not reproduce locally in that batch.
> h3. Expected behavior
> Threads that have already terminated should be ignored while constructing the 
> leak report because they are not leaks. The reporting path must not throw an 
> NPE.
> h3. Related issue
> KAFKA-17189 (https://issues.apache.org/jira/browse/KAFKA-17189) describes the 
> underlying snapshot-to-report race and proposes adding {{Thread::isAlive}} to 
> the leak-detector filter. This issue tracks the concrete 
> {{ClusterTestExtensions#afterEach}} NPE observed in CI.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to