From a6a4ddfef518a30da54face0a6d8d07b0a038c06 Mon Sep 17 00:00:00 2001 From: Amit Balode Date: Sat, 11 Apr 2026 20:51:06 +0530 Subject: [PATCH] HDFS-16029. Fix ArrayIndexOutOfBoundsException and divide-by-zero in InstrumentationService.Timer.getValues() --- .../InstrumentationService.java | 3 +++ .../TestInstrumentationService.java | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java index ee4455c9998df0..0cd07db4be03b2 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/service/instrumentation/InstrumentationService.java @@ -226,6 +226,9 @@ long[] getValues() { lock.lock(); try { long[] values = new long[4]; + if (last < 0) { + return values; + } values[LAST_TOTAL] = total[last]; values[LAST_OWN] = own[last]; int limit = (full) ? size : (last + 1); diff --git a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java index 86d42ccdf2d79c..6a7e1e731fe0e9 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java +++ b/hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/lib/service/instrumentation/TestInstrumentationService.java @@ -232,6 +232,24 @@ public void timer() throws Exception { assertEquals(json.get("avgOwn"), values[InstrumentationService.Timer.AVG_OWN]); } + @Test + public void timerGetValuesBeforeAnyCron() throws Exception { + // HDFS-16029: getValues() on a fresh Timer (last == -1) must not throw + // ArrayIndexOutOfBoundsException or divide-by-zero; it should return zeros. + InstrumentationService.Timer timer = new InstrumentationService.Timer(2); + long[] values = timer.getValues(); + assertEquals(4, values.length); + assertEquals(0, values[InstrumentationService.Timer.LAST_TOTAL]); + assertEquals(0, values[InstrumentationService.Timer.LAST_OWN]); + assertEquals(0, values[InstrumentationService.Timer.AVG_TOTAL]); + assertEquals(0, values[InstrumentationService.Timer.AVG_OWN]); + + // toJSONString() also calls getValues() via getJSON() — must not throw either + String json = timer.toJSONString(); + assertNotNull(json); + assertTrue(json.contains("lastTotal")); + } + @Test public void sampler() throws Exception { final long value[] = new long[1];