From d6dd6c07085ec058e3348d1563cdc3b85d94e007 Mon Sep 17 00:00:00 2001 From: Christophe TARDELLA Date: Mon, 7 Oct 2019 10:00:57 +0200 Subject: [PATCH] Add a class cast check to avoid ClassCastException FIX #504 Signed-off-by: Christophe TARDELLA --- .../hotspot/MemoryAllocationExports.java | 10 ++++++-- .../hotspot/MemoryAllocationExportsTest.java | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java index afad2590f..b5a2754d7 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java @@ -25,8 +25,10 @@ public class MemoryAllocationExports extends Collector { public MemoryAllocationExports() { AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter); - for (GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) { - ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null); + for (GarbageCollectorMXBean garbageCollectorMXBean : getGarbageCollectorMXBeans()) { + if (garbageCollectorMXBean instanceof NotificationEmitter) { + ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null); + } } } @@ -97,4 +99,8 @@ private static long getAndSet(Map map, String key, long value) { return last == null ? 0 : last; } } + + protected List getGarbageCollectorMXBeans() { + return ManagementFactory.getGarbageCollectorMXBeans(); + } } diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java index 0eb4d38c2..367b86333 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java @@ -2,6 +2,13 @@ import io.prometheus.client.Counter; import org.junit.Test; +import org.mockito.Mockito; + +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import java.lang.management.GarbageCollectorMXBean; +import java.util.Arrays; +import java.util.List; import static org.junit.Assert.assertEquals; @@ -42,4 +49,20 @@ public void testListenerLogic() { listener.handleMemoryPool("TestPool", 17, 20); assertEquals(153, child.get(), 0.001); } + + @Test + public void testConstructorShouldIgnoreNotNotificationEmitterClasses() { + final GarbageCollectorMXBean notificationEmitterMXBean = Mockito.mock(GarbageCollectorMXBean.class, Mockito.withSettings().extraInterfaces(NotificationEmitter.class)); + final GarbageCollectorMXBean notNotificationEmitterMXBean = Mockito.mock(GarbageCollectorMXBean.class); + + new MemoryAllocationExports() { + @Override + protected List getGarbageCollectorMXBeans() { + return Arrays.asList(notificationEmitterMXBean, notNotificationEmitterMXBean); + } + }; + + Mockito.verify((NotificationEmitter) notificationEmitterMXBean).addNotificationListener(Mockito.any(MemoryAllocationExports.AllocationCountingNotificationListener.class), Mockito.isNull(NotificationFilter.class), Mockito.isNull()); + Mockito.verifyZeroInteractions(notNotificationEmitterMXBean); + } }