This is an automated email from the ASF dual-hosted git repository.

viirya pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new ea78aeb656e1 [SPARK-55271][SS] Fix NullPointerException in Kafka 
micro-batch streaming metrics reporting
ea78aeb656e1 is described below

commit ea78aeb656e136962940ed6f97b2d4f6d3a4a5e2
Author: zahed1994 <[email protected]>
AuthorDate: Thu Aug 27 07:45:48 2026 -0700

    [SPARK-55271][SS] Fix NullPointerException in Kafka micro-batch streaming 
metrics reporting
    
    ### What changes were proposed in this pull request?
    
    This PR fixes a `NullPointerException` in `KafkaMicroBatchStream.metrics()` 
during Kafka micro-batch streaming progress reporting (`finishTrigger`).
    
    Specifically, `KafkaMicroBatchStream.metrics()` checked 
`latestAvailablePartitionOffsets.isDefined` before extracting partition 
offsets. If `latestAvailablePartitionOffsets` was `Some(null)`, `isDefined` 
returned `true`, causing `latestAvailablePartitionOffsets.get` to return `null` 
and throwing a `NullPointerException` when `.map()` was invoked on it.
    
    This PR updates the condition to `latestAvailablePartitionOffsets.exists(_ 
!= null)` to safely ensure partition offsets are non-null before invoking 
`.map()`.
    
    ### Why are the changes needed?
    
    When uninitialized partition offsets or race conditions occur during 
progress reporting (`finishTrigger`), `latestAvailablePartitionOffsets` can be 
`Some(null)`. Without this check, calling `.map()` on `null` throws a 
`NullPointerException`, crashing the entire streaming query job in production 
after batch execution.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No API changes. Fixes a `NullPointerException` in progress reporting 
metrics.
    
    ### How was this patch tested?
    
    Added unit test assertion in `KafkaMicroBatchSourceSuite`.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    No.
    
    Closes #58133 from zahed1994/SPARK-55271-kafka-streaming-metrics-npe.
    
    Authored-by: zahed1994 <[email protected]>
    Signed-off-by: Liang-Chi Hsieh <[email protected]>
    (cherry picked from commit 3a9f11ff9fae4fb3870a9cd73b1992c3f86a6eac)
    Signed-off-by: Liang-Chi Hsieh <[email protected]>
---
 .../scala/org/apache/spark/sql/kafka010/KafkaMicroBatchStream.scala     | 2 +-
 .../org/apache/spark/sql/kafka010/KafkaMicroBatchSourceSuite.scala      | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git 
a/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchStream.scala
 
b/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchStream.scala
index e94c08cd2b18..2144cd29b758 100644
--- 
a/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchStream.scala
+++ 
b/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchStream.scala
@@ -514,7 +514,7 @@ object KafkaMicroBatchStream extends Logging {
       latestAvailablePartitionOffsets: Option[PartitionOffsetMap]): 
ju.Map[String, String] = {
     val offset = Option(latestConsumedOffset.orElse(null))
 
-    if (offset.nonEmpty && latestAvailablePartitionOffsets.isDefined) {
+    if (offset.nonEmpty && latestAvailablePartitionOffsets.exists(_ != null)) {
       val consumedPartitionOffsets = 
offset.map(KafkaSourceOffset(_)).get.partitionToOffsets
       val offsetsBehindLatest = latestAvailablePartitionOffsets.get
         .map(partitionOffset => partitionOffset._2 -
diff --git 
a/connector/kafka-0-10-sql/src/test/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchSourceSuite.scala
 
b/connector/kafka-0-10-sql/src/test/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchSourceSuite.scala
index 66a1bf00f87f..b148af71412e 100644
--- 
a/connector/kafka-0-10-sql/src/test/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchSourceSuite.scala
+++ 
b/connector/kafka-0-10-sql/src/test/scala/org/apache/spark/sql/kafka010/KafkaMicroBatchSourceSuite.scala
@@ -1930,6 +1930,8 @@ abstract class KafkaMicroBatchV2SourceSuite extends 
KafkaMicroBatchSourceSuiteBa
 
     // test null latestAvailablePartitionOffsets
     assert(KafkaMicroBatchStream.metrics(Optional.ofNullable(offset), 
None).isEmpty)
+    assert(KafkaMicroBatchStream.metrics(
+      Optional.ofNullable(offset), 
Some(null).asInstanceOf[Option[PartitionOffsetMap]]).isEmpty)
   }
 
   test("SPARK-57438: metrics should not NPE when latestPartitionOffsets is 
null") {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to