Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BDE6011DCE for ; Tue, 9 Sep 2014 17:56:54 +0000 (UTC) Received: (qmail 61610 invoked by uid 500); 9 Sep 2014 17:56:54 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 61544 invoked by uid 500); 9 Sep 2014 17:56:54 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 61535 invoked by uid 99); 9 Sep 2014 17:56:54 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 09 Sep 2014 17:56:54 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 09 Sep 2014 17:56:31 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 3171623888A6; Tue, 9 Sep 2014 17:56:30 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1623862 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/SystemConfiguration.java test/java/org/apache/commons/configuration/TestSystemConfiguration.java Date: Tue, 09 Sep 2014 17:56:30 -0000 To: commits@commons.apache.org From: oheger@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140909175630.3171623888A6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: oheger Date: Tue Sep 9 17:56:29 2014 New Revision: 1623862 URL: http://svn.apache.org/r1623862 Log: [CONFIGURATION-570] Alternative implementation of SystemConfiguration.getKeys(). In order to avoid ConcurrentModificationExceptions when iterating over the keys of a SystemConfiguration, the iterator returned for the keys is now a snapshot. Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/SystemConfiguration.java commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestSystemConfiguration.java Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/SystemConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/SystemConfiguration.java?rev=1623862&r1=1623861&r2=1623862&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/SystemConfiguration.java (original) +++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/SystemConfiguration.java Tue Sep 9 17:56:29 2014 @@ -104,4 +104,14 @@ public class SystemConfiguration extends System.setProperty(key, value); } } + + /** + * {@inheritDoc} This implementation returns a snapshot of the keys in the + * system properties. If another thread modifies system properties concurrently, + * these changes are not reflected by the iterator returned by this method. + */ + @Override + protected Iterator getKeysInternal() { + return System.getProperties().stringPropertyNames().iterator(); + } } Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestSystemConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestSystemConfiguration.java?rev=1623862&r1=1623861&r2=1623862&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestSystemConfiguration.java (original) +++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestSystemConfiguration.java Tue Sep 9 17:56:29 2014 @@ -22,7 +22,9 @@ import static org.junit.Assert.assertTru import java.io.File; import java.io.IOException; +import java.util.Iterator; import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; import org.apache.commons.configuration.ex.ConfigurationException; import org.apache.commons.configuration.io.FileHandler; @@ -92,4 +94,61 @@ public class TestSystemConfiguration assertEquals("System property not changed", "true", System.getProperty(testProperty)); } + + /** + * Tests an append operation with a system configuration while system + * properties are modified from another thread. This is related to + * CONFIGURATION-570. + */ + @Test + public void testAppendWhileConcurrentAccess() throws InterruptedException + { + final AtomicBoolean stop = new AtomicBoolean(); + final String property = + SystemConfiguration.class.getName() + ".testProperty"; + Thread t = new Thread() + { + @Override + public void run() + { + boolean setValue = true; + while (!stop.get()) + { + if (setValue) + { + System.setProperty(property, "true"); + } + else + { + System.clearProperty(property); + } + setValue = !setValue; + } + } + }; + try + { + t.start(); + + SystemConfiguration config = new SystemConfiguration(); + PropertiesConfiguration props = new PropertiesConfiguration(); + props.append(config); + + stop.set(true); + t.join(); + for (Iterator keys = config.getKeys(); keys.hasNext();) + { + String key = keys.next(); + if (!property.equals(key)) + { + assertEquals("Wrong value for " + key, + config.getString(key), props.getString(key)); + } + } + } + finally + { + System.clearProperty(property); + } + } }