From ab8447079fe9efda828cdef2fe810d4c0027ab7e Mon Sep 17 00:00:00 2001 From: neugartf Date: Wed, 25 Sep 2024 02:30:21 +0200 Subject: [PATCH 1/4] Fix ConcurrentModificationException #6732 --- .../api/internal/ConfigUtil.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java index 56d2d378d72..4ff6d622a42 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java @@ -5,8 +5,12 @@ package io.opentelemetry.api.internal; +import java.util.AbstractMap; +import java.util.HashSet; import java.util.Locale; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import javax.annotation.Nullable; /** @@ -33,10 +37,21 @@ private ConfigUtil() {} */ public static String getString(String key, String defaultValue) { String normalizedKey = normalizePropertyKey(key); + Set> properties = + new HashSet<>(System.getProperties().entrySet()) + .stream() + .filter( + entry -> entry.getKey() instanceof String && entry.getValue() instanceof String) + .map( + entry -> + new AbstractMap.SimpleEntry<>( + (String) entry.getKey(), (String) entry.getValue())) + .collect(Collectors.>toSet()); + String systemProperty = - System.getProperties().entrySet().stream() - .filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey().toString()))) - .map(entry -> entry.getValue().toString()) + properties.stream() + .filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey()))) + .map(Map.Entry::getValue) .findFirst() .orElse(null); if (systemProperty != null) { From b115c5a6e2f469f437026fad2319ae4588b60cd0 Mon Sep 17 00:00:00 2001 From: neugartf Date: Thu, 26 Sep 2024 21:45:35 +0200 Subject: [PATCH 2/4] Move to stringPropertyNames in order to iterate on a stable list. --- .../opentelemetry/api/internal/ConfigUtil.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java index 4ff6d622a42..c4cfde8a1a2 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java @@ -6,7 +6,6 @@ package io.opentelemetry.api.internal; import java.util.AbstractMap; -import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -38,15 +37,12 @@ private ConfigUtil() {} public static String getString(String key, String defaultValue) { String normalizedKey = normalizePropertyKey(key); Set> properties = - new HashSet<>(System.getProperties().entrySet()) - .stream() - .filter( - entry -> entry.getKey() instanceof String && entry.getValue() instanceof String) - .map( - entry -> - new AbstractMap.SimpleEntry<>( - (String) entry.getKey(), (String) entry.getValue())) - .collect(Collectors.>toSet()); + System.getProperties().stringPropertyNames().stream() + .map( + propertyName -> + new AbstractMap.SimpleEntry<>(propertyName, System.getProperty(propertyName))) + .filter(entry -> entry.getKey() != null) + .collect(Collectors.>toSet()); String systemProperty = properties.stream() From af488636cc61f791704f39a47439fb6c4262cb24 Mon Sep 17 00:00:00 2001 From: neugartf Date: Thu, 26 Sep 2024 22:29:20 +0200 Subject: [PATCH 3/4] Improve stream handling of system property --- .../opentelemetry/api/internal/ConfigUtil.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java index c4cfde8a1a2..7ddbed24740 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java @@ -5,11 +5,9 @@ package io.opentelemetry.api.internal; -import java.util.AbstractMap; import java.util.Locale; import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.Objects; import javax.annotation.Nullable; /** @@ -36,18 +34,12 @@ private ConfigUtil() {} */ public static String getString(String key, String defaultValue) { String normalizedKey = normalizePropertyKey(key); - Set> properties = - System.getProperties().stringPropertyNames().stream() - .map( - propertyName -> - new AbstractMap.SimpleEntry<>(propertyName, System.getProperty(propertyName))) - .filter(entry -> entry.getKey() != null) - .collect(Collectors.>toSet()); String systemProperty = - properties.stream() - .filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey()))) - .map(Map.Entry::getValue) + System.getProperties().stringPropertyNames().stream() + .filter(propertyName -> normalizedKey.equals(normalizePropertyKey(propertyName))) + .map(System::getProperty) + .filter(Objects::nonNull) .findFirst() .orElse(null); if (systemProperty != null) { From d7364062928d38afccbb3613484cf1789cf37594 Mon Sep 17 00:00:00 2001 From: neugartf Date: Sun, 29 Sep 2024 20:12:33 +0200 Subject: [PATCH 4/4] Cloning properties in order to safely iterate over them --- .../opentelemetry/api/internal/ConfigUtil.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java index 7ddbed24740..304a8ddf740 100644 --- a/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java +++ b/api/all/src/main/java/io/opentelemetry/api/internal/ConfigUtil.java @@ -8,6 +8,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Properties; import javax.annotation.Nullable; /** @@ -35,13 +36,16 @@ private ConfigUtil() {} public static String getString(String key, String defaultValue) { String normalizedKey = normalizePropertyKey(key); + // Cloning in order to avoid ConcurrentModificationException + // see https://github.com/open-telemetry/opentelemetry-java/issues/6732 String systemProperty = - System.getProperties().stringPropertyNames().stream() - .filter(propertyName -> normalizedKey.equals(normalizePropertyKey(propertyName))) - .map(System::getProperty) - .filter(Objects::nonNull) - .findFirst() - .orElse(null); + ((Properties) System.getProperties().clone()) + .stringPropertyNames().stream() + .filter(propertyName -> normalizedKey.equals(normalizePropertyKey(propertyName))) + .map(System::getProperty) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); if (systemProperty != null) { return systemProperty; }