From 41eb0d922b88428111b554c044fdc5942afa22bb Mon Sep 17 00:00:00 2001 From: mharmer Date: Tue, 11 Dec 2018 14:02:37 -0800 Subject: [PATCH] Fixing a potential ConcurrentModificationException that could occur when running Ant with the Parallel-Ant executor. This closes #81 pull request at github/apache/ant --- CONTRIBUTORS | 1 + WHATSNEW | 4 ++ contributors.xml | 4 ++ src/main/org/apache/tools/ant/Project.java | 44 ++++++++++++++-------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 9b0c263a2..c6338ef7c 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -251,6 +251,7 @@ Mario Frasca Mariusz Nowostawski Mark A. Ziesemer Mark DeLaFranier +Mark Harmer Mark Hecker Mark Niggemann Mark R. Diggory diff --git a/WHATSNEW b/WHATSNEW index a74856e45..9229d4825 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -33,6 +33,10 @@ Fixed bugs: of the destination directory. Bugzilla Report 62890 + * Fixes a potential java.util.ConcurrentModificationException in + org.apache.tools.ant.Project#getCopyOfReferences. + Github Pull Request #81 + Other changes: -------------- diff --git a/contributors.xml b/contributors.xml index ebf03ee77..c56bd2454 100644 --- a/contributors.xml +++ b/contributors.xml @@ -1045,6 +1045,10 @@ Mark DeLaFranier + + Mark + Harmer + Mark Hecker diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java index 62aafbc4c..39a83a476 100644 --- a/src/main/org/apache/tools/ant/Project.java +++ b/src/main/org/apache/tools/ant/Project.java @@ -140,6 +140,9 @@ public class Project implements ResourceFactory { private String description; + /** lock object used when adding/removing references */ + private final Object referencesLock = new Object(); + /** Map of references within the project (paths etc) (String to Object). */ private final Hashtable references = new AntRefTable(); @@ -1971,17 +1974,19 @@ public class Project implements ResourceFactory { * @param value The value of the reference. */ public void addReference(final String referenceName, final Object value) { - final Object old = ((AntRefTable) references).getReal(referenceName); - if (old == value) { - // no warning, this is not changing anything - return; - } - if (old != null && !(old instanceof UnknownElement)) { - log("Overriding previous definition of reference to " + referenceName, - MSG_VERBOSE); + synchronized (referencesLock) { + final Object old = ((AntRefTable) references).getReal(referenceName); + if (old == value) { + // no warning, this is not changing anything + return; + } + if (old != null && !(old instanceof UnknownElement)) { + log("Overriding previous definition of reference to " + referenceName, + MSG_VERBOSE); + } + log("Adding reference: " + referenceName, MSG_DEBUG); + references.put(referenceName, value); } - log("Adding reference: " + referenceName, MSG_DEBUG); - references.put(referenceName, value); } /** @@ -2002,7 +2007,9 @@ public class Project implements ResourceFactory { * @since Ant 1.8.0 */ public boolean hasReference(final String key) { - return references.containsKey(key); + synchronized (referencesLock) { + return references.containsKey(key); + } } /** @@ -2015,7 +2022,9 @@ public class Project implements ResourceFactory { * @since Ant 1.8.1 */ public Map getCopyOfReferences() { - return new HashMap<>(references); + synchronized (referencesLock) { + return new HashMap<>(references); + } } /** @@ -2029,11 +2038,14 @@ public class Project implements ResourceFactory { * there is no such reference in the project, with type inference. */ public T getReference(final String key) { - @SuppressWarnings("unchecked") - final T ret = (T) references.get(key); - if (ret != null) { - return ret; + synchronized (referencesLock) { + @SuppressWarnings("unchecked") + final T ret = (T) references.get(key); + if (ret != null) { + return ret; + } } + if (!key.equals(MagicNames.REFID_PROPERTY_HELPER)) { try { if (PropertyHelper.getPropertyHelper(this).containsProperties(key)) {