Browse Source

Fixing a potential ConcurrentModificationException that could occur when running Ant with the Parallel-Ant executor.

This closes #81 pull request at github/apache/ant
master
mharmer Jaikiran Pai 6 years ago
parent
commit
41eb0d922b
4 changed files with 37 additions and 16 deletions
  1. +1
    -0
      CONTRIBUTORS
  2. +4
    -0
      WHATSNEW
  3. +4
    -0
      contributors.xml
  4. +28
    -16
      src/main/org/apache/tools/ant/Project.java

+ 1
- 0
CONTRIBUTORS View File

@@ -251,6 +251,7 @@ Mario Frasca
Mariusz Nowostawski
Mark A. Ziesemer
Mark DeLaFranier
Mark Harmer
Mark Hecker
Mark Niggemann
Mark R. Diggory


+ 4
- 0
WHATSNEW View File

@@ -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:
--------------


+ 4
- 0
contributors.xml View File

@@ -1045,6 +1045,10 @@
<first>Mark</first>
<last>DeLaFranier</last>
</name>
<name>
<first>Mark</first>
<last>Harmer</last>
</name>
<name>
<first>Mark</first>
<last>Hecker</last>


+ 28
- 16
src/main/org/apache/tools/ant/Project.java View File

@@ -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<String, Object> 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<String, Object> 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> 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)) {


Loading…
Cancel
Save