HADOOP-11274. ConcurrentModificationException in Configuration Copy Constructor. Contributed by Junping Du.

This commit is contained in:
Jing Zhao 2014-11-06 16:07:50 -08:00
parent a19123df9a
commit 22ecbd4ab3
2 changed files with 46 additions and 38 deletions

View File

@ -381,6 +381,9 @@ Release 2.6.0 - UNRELEASED
HADOOP-11253. Hadoop streaming test TestStreamXmlMultipleRecords fails on HADOOP-11253. Hadoop streaming test TestStreamXmlMultipleRecords fails on
Windows. (Varun Vasudev via wheat9) Windows. (Varun Vasudev via wheat9)
HADOOP-11274. ConcurrentModificationException in Configuration Copy Constructor.
(Junping Du via jing9)
BREAKDOWN OF HDFS-6134 AND HADOOP-10150 SUBTASKS AND RELATED JIRAS BREAKDOWN OF HDFS-6134 AND HADOOP-10150 SUBTASKS AND RELATED JIRAS
HADOOP-10734. Implement high-performance secure random number sources. HADOOP-10734. Implement high-performance secure random number sources.

View File

@ -690,26 +690,26 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Configuration(Configuration other) { public Configuration(Configuration other) {
this.resources = (ArrayList<Resource>) other.resources.clone(); synchronized(other) {
synchronized(other) { this.resources = (ArrayList<Resource>) other.resources.clone();
if (other.properties != null) { if (other.properties != null) {
this.properties = (Properties)other.properties.clone(); this.properties = (Properties)other.properties.clone();
} }
if (other.overlay!=null) { if (other.overlay!=null) {
this.overlay = (Properties)other.overlay.clone(); this.overlay = (Properties)other.overlay.clone();
} }
this.updatingResource = new HashMap<String, String[]>(other.updatingResource); this.updatingResource = new HashMap<String, String[]>(other.updatingResource);
this.finalParameters = new HashSet<String>(other.finalParameters); this.finalParameters = new HashSet<String>(other.finalParameters);
}
this.classLoader = other.classLoader;
this.loadDefaults = other.loadDefaults;
setQuietMode(other.getQuietMode());
}
synchronized(Configuration.class) { synchronized(Configuration.class) {
REGISTRY.put(this, null); REGISTRY.put(this, null);
} }
this.classLoader = other.classLoader;
this.loadDefaults = other.loadDefaults;
setQuietMode(other.getQuietMode());
} }
/** /**
@ -1019,26 +1019,28 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
getProps().setProperty(name, value); getProps().setProperty(name, value);
String newSource = (source == null ? "programatically" : source); String newSource = (source == null ? "programatically" : source);
if (!isDeprecated(name)) { synchronized (this) {
updatingResource.put(name, new String[] {newSource}); if (!isDeprecated(name)) {
String[] altNames = getAlternativeNames(name); updatingResource.put(name, new String[] {newSource});
if(altNames != null) { String[] altNames = getAlternativeNames(name);
for(String n: altNames) { if(altNames != null) {
if(!n.equals(name)) { for(String n: altNames) {
getOverlay().setProperty(n, value); if(!n.equals(name)) {
getProps().setProperty(n, value); getOverlay().setProperty(n, value);
updatingResource.put(n, new String[] {newSource}); getProps().setProperty(n, value);
updatingResource.put(n, new String[] {newSource});
}
} }
} }
} }
} else {
else { String[] names = handleDeprecation(deprecationContext.get(), name);
String[] names = handleDeprecation(deprecationContext.get(), name); String altSource = "because " + name + " is deprecated";
String altSource = "because " + name + " is deprecated"; for(String n : names) {
for(String n : names) { getOverlay().setProperty(n, value);
getOverlay().setProperty(n, value); getProps().setProperty(n, value);
getProps().setProperty(n, value); updatingResource.put(n, new String[] {altSource});
updatingResource.put(n, new String[] {altSource}); }
} }
} }
} }
@ -2269,7 +2271,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
* *
* @return final parameter set. * @return final parameter set.
*/ */
public Set<String> getFinalParameters() { public synchronized Set<String> getFinalParameters() {
return new HashSet<String>(finalParameters); return new HashSet<String>(finalParameters);
} }
@ -2532,14 +2534,18 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
if (value != null) { if (value != null) {
if (!finalParameters.contains(attr)) { if (!finalParameters.contains(attr)) {
properties.setProperty(attr, value); properties.setProperty(attr, value);
updatingResource.put(attr, source); synchronized(this) {
updatingResource.put(attr, source);
}
} else if (!value.equals(properties.getProperty(attr))) { } else if (!value.equals(properties.getProperty(attr))) {
LOG.warn(name+":an attempt to override final parameter: "+attr LOG.warn(name+":an attempt to override final parameter: "+attr
+"; Ignoring."); +"; Ignoring.");
} }
} }
if (finalParameter) { if (finalParameter) {
finalParameters.add(attr); synchronized(this) {
finalParameters.add(attr);
}
} }
} }
@ -2733,7 +2739,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
} }
@Override @Override
public void readFields(DataInput in) throws IOException { public synchronized void readFields(DataInput in) throws IOException {
clear(); clear();
int size = WritableUtils.readVInt(in); int size = WritableUtils.readVInt(in);
for(int i=0; i < size; ++i) { for(int i=0; i < size; ++i) {
@ -2745,9 +2751,8 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
} }
} }
//@Override
@Override @Override
public void write(DataOutput out) throws IOException { public synchronized void write(DataOutput out) throws IOException {
Properties props = getProps(); Properties props = getProps();
WritableUtils.writeVInt(out, props.size()); WritableUtils.writeVInt(out, props.size());
for(Map.Entry<Object, Object> item: props.entrySet()) { for(Map.Entry<Object, Object> item: props.entrySet()) {