diff options
author | Igor Fedorenko | 2014-07-30 03:16:11 +0000 |
---|---|---|
committer | Igor Fedorenko | 2014-07-30 03:16:11 +0000 |
commit | 4b83a0f17e307dbc9ed5554ee6f41c5eeff4206e (patch) | |
tree | 4f3b34e18a65093d3ba5a777e3f1578124eb6681 | |
parent | 04dade2a891c158558ea8aebe36e5c8ba2dbe111 (diff) | |
download | m2e-core-4b83a0f17e307dbc9ed5554ee6f41c5eeff4206e.tar.gz m2e-core-4b83a0f17e307dbc9ed5554ee6f41c5eeff4206e.tar.xz m2e-core-4b83a0f17e307dbc9ed5554ee6f41c5eeff4206e.zip |
440696 guard against ConcurrentModificationException during Properties.entrySet
Change-Id: Ida19217c41836ef788a7a25913b9c5388fe460fc
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
5 files changed, 37 insertions, 7 deletions
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java index 1ebfc821..f0a01d9a 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java @@ -13,7 +13,9 @@ package org.eclipse.m2e.core.internal; import java.io.File; import java.util.Collection; +import java.util.ConcurrentModificationException; import java.util.HashSet; +import java.util.Properties; import java.util.Set; import java.util.Stack; @@ -150,4 +152,23 @@ public class M2EUtils { } return false; } + + /** + * Thread-safe properties copy implementation. + * <p> + * {@link Properties#entrySet()} iterator is not thread safe and fails with {@link ConcurrentModificationException} if + * the source properties "is structurally modified at any time after the iterator is created". The solution is to use + * thread-safe {@link Properties#stringPropertyNames()} enumerate and copy properties. + * + * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=440696 + * @since 1.6 + */ + public static void copyProperties(Properties to, Properties from) { + for(String key : from.stringPropertyNames()) { + String value = from.getProperty(key); + if(value != null) { + to.put(key, value); + } + } + } } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java index 426f7cc1..00d8b661 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenExecutionContext.java @@ -11,6 +11,8 @@ package org.eclipse.m2e.core.internal.embedder; +import static org.eclipse.m2e.core.internal.M2EUtils.copyProperties; + import java.util.ArrayDeque; import java.util.Collections; import java.util.Deque; @@ -219,7 +221,7 @@ public class MavenExecutionContext implements IMavenExecutionContext { // oddly, there are no unit tests that fail if this is commented out Properties systemProperties = new Properties(); EnvironmentUtils.addEnvVars(systemProperties); - systemProperties.putAll(System.getProperties()); + copyProperties(systemProperties, System.getProperties()); request.setSystemProperties(systemProperties); } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java index 30757f0b..5097704b 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java @@ -11,6 +11,8 @@ package org.eclipse.m2e.core.internal.embedder; +import static org.eclipse.m2e.core.internal.M2EUtils.copyProperties; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -245,7 +247,7 @@ public class MavenImpl implements IMaven, IMavenConfigurationChangeListener { request.getUserProperties().put(ConfigurationProperties.USER_AGENT, MavenPluginActivator.getUserAgent()); EnvironmentUtils.addEnvVars(request.getSystemProperties()); - request.getSystemProperties().putAll(System.getProperties()); + copyProperties(request.getSystemProperties(), System.getProperties()); request.setCacheNotFound(true); request.setCacheTransferError(true); @@ -453,7 +455,10 @@ public class MavenImpl implements IMaven, IMavenConfigurationChangeListener { if(reload) { // TODO: Can't that delegate to buildSettings()? SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); - request.setSystemProperties(System.getProperties()); + // 440696 guard against ConcurrentModificationException + Properties systemProperties = new Properties(); + copyProperties(systemProperties, System.getProperties()); + request.setSystemProperties(systemProperties); if(mavenConfiguration.getGlobalSettingsFile() != null) { request.setGlobalSettingsFile(new File(mavenConfiguration.getGlobalSettingsFile())); } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/launch/MavenExternalRuntime.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/launch/MavenExternalRuntime.java index b7fc27e2..64c6566a 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/launch/MavenExternalRuntime.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/launch/MavenExternalRuntime.java @@ -11,6 +11,8 @@ package org.eclipse.m2e.core.internal.launch; +import static org.eclipse.m2e.core.internal.M2EUtils.copyProperties; + import java.io.File; import java.io.FileInputStream; import java.net.URL; @@ -134,7 +136,7 @@ public class MavenExternalRuntime extends AbstractMavenRuntime { }; Properties properties = new Properties(); - properties.putAll(System.getProperties()); + copyProperties(properties, System.getProperties()); properties.put(PROPERTY_MAVEN_HOME, location); ConfigurationParser parser = new ConfigurationParser(handler, properties); @@ -224,7 +226,7 @@ public class MavenExternalRuntime extends AbstractMavenRuntime { VersionHandler handler = new VersionHandler(); Properties properties = new Properties(); - properties.putAll(System.getProperties()); + copyProperties(properties, System.getProperties()); properties.put(PROPERTY_MAVEN_HOME, location); ConfigurationParser parser = new ConfigurationParser(handler, properties); diff --git a/org.eclipse.m2e.logback.configuration/src/org/eclipse/m2e/logback/configuration/LogHelper.java b/org.eclipse.m2e.logback.configuration/src/org/eclipse/m2e/logback/configuration/LogHelper.java index 2621be1b..6a49fa25 100644 --- a/org.eclipse.m2e.logback.configuration/src/org/eclipse/m2e/logback/configuration/LogHelper.java +++ b/org.eclipse.m2e.logback.configuration/src/org/eclipse/m2e/logback/configuration/LogHelper.java @@ -22,8 +22,8 @@ public class LogHelper { public static void logJavaProperties(Logger log) { Properties javaProperties = System.getProperties(); SortedMap<String, String> sortedProperties = new TreeMap<String, String>(); - for(Object key : javaProperties.keySet()) { - sortedProperties.put((String) key, (String) javaProperties.get(key)); + for(String key : javaProperties.stringPropertyNames()) { + sortedProperties.put(key, javaProperties.getProperty(key)); } log.debug("Java properties (ordered by property name):"); //$NON-NLS-1$ for(String key : sortedProperties.keySet()) { |