You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by rg...@apache.org on 2009/09/30 01:38:53 UTC
svn commit: r820124 - in
/commons/proper/configuration/branches/CONFIGURATION_390: ./ conf/
src/java/org/apache/commons/configuration/
src/test/org/apache/commons/configuration/
src/test/org/apache/commons/configuration/reloading/
Author: rgoers
Date: Tue Sep 29 23:38:52 2009
New Revision: 820124
URL: http://svn.apache.org/viewvc?rev=820124&view=rev
Log:
Fix memory leak on reloading. Have DynamicCombinedConfiguration participate in locking
Added:
commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder4.xml
- copied, changed from r819418, commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder2.xml
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/Lock.java
Modified:
commons/proper/configuration/branches/CONFIGURATION_390/pom.xml
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/CombinedConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/DynamicCombinedConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/HierarchicalReloadableConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/XMLConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/Logging.java
commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestDynamicCombinedConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java
Copied: commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder4.xml (from r819418, commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder2.xml)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder4.xml?p2=commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder4.xml&p1=commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder2.xml&r1=819418&r2=820124&rev=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder2.xml (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/conf/testMultiTenentConfigurationBuilder4.xml Tue Sep 29 23:38:52 2009
@@ -4,11 +4,15 @@
<header>
<result delimiterParsingDisabled="true" forceReloadCheck="true" loggerName="TestLogger"
config-class="org.apache.commons.configuration.DynamicCombinedConfiguration"
- keyPattern="$${sys:Id}">
+ keyPattern="$${test:Id}">
<nodeCombiner config-class="org.apache.commons.configuration.tree.MergeCombiner"/>
<expressionEngine
config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
</result>
+ <lookups>
+ <lookup config-prefix="test"
+ config-class="org.apache.commons.configuration.TestDynamicCombinedConfiguration$ThreadLookup"/>
+ </lookups>
<entity-resolver catalogFiles="catalog.xml"/>
<providers>
<provider config-tag="multifile"
@@ -17,19 +21,19 @@
</providers>
</header>
<override>
- <multifile filePattern="testMultiConfiguration_$$${sys:Id}.xml"
+ <multifile filePattern="testMultiConfiguration_$$${test:Id}.xml"
config-name="clientConfig" delimiterParsingDisabled="true" schemaValidation="true">
<expressionEngine
config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
<reloadingStrategy refreshDelay="500"
- config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
+ config-class="org.apache.commons.configuration.reloading.FileRandomReloadingStrategy"/>
</multifile>
<xml fileName="testMultiConfiguration_default.xml"
config-name="defaultConfig" delimiterParsingDisabled="true" schemaValidation="true">
<expressionEngine
config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
<reloadingStrategy refreshDelay="500"
- config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"/>
+ config-class="org.apache.commons.configuration.reloading.FileRandomReloadingStrategy"/>
</xml>
</override>
</configuration>
\ No newline at end of file
Modified: commons/proper/configuration/branches/CONFIGURATION_390/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/pom.xml?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/pom.xml (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/pom.xml Tue Sep 29 23:38:52 2009
@@ -486,6 +486,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
+ <!-- Uncomment to enable profiling unit tests -->
+ <!-- <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine> -->
<forkMode>once</forkMode>
<excludes>
<exclude>**/TestWebdavConfigurationBuilder.java</exclude>
@@ -584,6 +586,14 @@
</plugins>
</build>
</profile>
+ <!-- Uncomment this and set the path accordingly to enable YourKit -->
+ <!-- http://www.yourkit.com/docs/80/help/agent.jsp -->
+ <!-- <profile>
+ <id>yourkit-profile</id>
+ <properties>
+ <yourkit.home>/Applications/YourKit_Java_Profiler_8.0.17.app/</yourkit.home>
+ </properties>
+ </profile> -->
</profiles>
<reporting>
<plugins>
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java Tue Sep 29 23:38:52 2009
@@ -103,7 +103,7 @@
protected ReloadingStrategy strategy;
/** A lock object for protecting reload operations.*/
- protected Object reloadLock = new Object();
+ protected Object reloadLock = new Lock("AbstractFileConfiguration");
/** Stores the encoding of the configuration file.*/
private String encoding;
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/CombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/CombinedConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/CombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/CombinedConfiguration.java Tue Sep 29 23:38:52 2009
@@ -234,6 +234,18 @@
clear();
}
+ public CombinedConfiguration(NodeCombiner comb, Lock lock)
+ {
+ super(lock);
+ setNodeCombiner((comb != null) ? comb : DEFAULT_COMBINER);
+ clear();
+ }
+
+ public CombinedConfiguration(Lock lock)
+ {
+ this(null, lock);
+ }
+
/**
* Creates a new instance of <code>CombinedConfiguration</code> that uses
* a union combiner.
@@ -242,7 +254,7 @@
*/
public CombinedConfiguration()
{
- this(null);
+ this(null, null);
}
/*
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/DynamicCombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/DynamicCombinedConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/DynamicCombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/DynamicCombinedConfiguration.java Tue Sep 29 23:38:52 2009
@@ -32,8 +32,10 @@
import org.apache.commons.configuration.tree.ConfigurationNode;
import org.apache.commons.configuration.tree.ExpressionEngine;
import org.apache.commons.configuration.tree.NodeCombiner;
+import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.lang.text.StrSubstitutor;
/**
* DynamicCombinedConfiguration allows a set of CombinedConfigurations to be used. Each CombinedConfiguration
@@ -73,8 +75,12 @@
/** Stores the combiner. */
private NodeCombiner nodeCombiner;
+ private Lock reloadLock = new Lock("DynamicCombinedConfiguration");
+
/** The name of the logger to use for each CombinedConfiguration */
- private String loggerName;
+ private String loggerName = DynamicCombinedConfiguration.class.getName();
+
+ StrSubstitutor localSubst = new StrSubstitutor(new ConfigurationInterpolator());
/**
* Creates a new instance of <code>CombinedConfiguration</code> and
@@ -88,6 +94,7 @@
super();
setNodeCombiner(comb);
setIgnoreReloadExceptions(false);
+ setLogger(LogFactory.getLog(DynamicCombinedConfiguration.class));
}
/**
@@ -100,6 +107,7 @@
{
super();
setIgnoreReloadExceptions(false);
+ setLogger(LogFactory.getLog(DynamicCombinedConfiguration.class));
}
public void setKeyPattern(String pattern)
@@ -754,14 +762,14 @@
private CombinedConfiguration getCurrentConfig()
{
- String key = getSubstitutor().replace(keyPattern);
+ String key = localSubst.replace(keyPattern);
CombinedConfiguration config;
synchronized (getNodeCombiner())
{
config = (CombinedConfiguration) configs.get(key);
if (config == null)
{
- config = new CombinedConfiguration(getNodeCombiner());
+ config = new CombinedConfiguration(getNodeCombiner(), reloadLock);
if (loggerName != null)
{
Log log = LogFactory.getLog(loggerName);
@@ -798,6 +806,10 @@
configs.put(key, config);
}
}
+ if (getLogger().isDebugEnabled())
+ {
+ getLogger().debug("Returning config for " + key + ": " + config);
+ }
return config;
}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/HierarchicalReloadableConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/HierarchicalReloadableConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/HierarchicalReloadableConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/HierarchicalReloadableConfiguration.java Tue Sep 29 23:38:52 2009
@@ -16,19 +16,21 @@
{
private final Object reloadLock;
+ private static final String LOCK_NAME = "HierarchicalReloadableConfigurationLock";
+
/**
* Creates a new instance of <code>HierarchicalReloadableConfiguration</code>.
*/
public HierarchicalReloadableConfiguration()
{
super();
- reloadLock = new Object();
+ reloadLock = new Lock(LOCK_NAME);
}
public HierarchicalReloadableConfiguration(Object lock)
{
super();
- reloadLock = lock == null ? new Object() : lock;
+ reloadLock = lock == null ? new Lock(LOCK_NAME) : lock;
}
/**
@@ -43,7 +45,7 @@
public HierarchicalReloadableConfiguration(HierarchicalConfiguration c)
{
super(c);
- reloadLock = new Object();
+ reloadLock = new Lock(LOCK_NAME);
}
Added: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/Lock.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/Lock.java?rev=820124&view=auto
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/Lock.java (added)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/Lock.java Tue Sep 29 23:38:52 2009
@@ -0,0 +1,36 @@
+package org.apache.commons.configuration;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: rgoers
+ * Date: Sep 29, 2009
+ * Time: 12:50:36 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class Lock
+{
+ private final String name;
+ private final int instanceId;
+
+ private static String counterLock = "Lock";
+ private static int counter = 0;
+
+ public Lock(String name)
+ {
+ this.name = name;
+ synchronized(counterLock)
+ {
+ instanceId = ++counter;
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String toString()
+ {
+ return "Lock: " + name + " id = " + instanceId;
+ }
+}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/MultiFileHierarchicalConfiguration.java Tue Sep 29 23:38:52 2009
@@ -39,9 +39,11 @@
import org.apache.commons.configuration.tree.ExpressionEngine;
import org.apache.commons.configuration.reloading.ReloadingStrategy;
import org.apache.commons.configuration.resolver.EntityResolverSupport;
+import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.lang.text.StrSubstitutor;
import org.xml.sax.EntityResolver;
import org.xml.sax.SAXParseException;
@@ -101,6 +103,8 @@
/** The EntityResolver */
private EntityResolver entityResolver;
+ private StrSubstitutor localSubst = new StrSubstitutor(new ConfigurationInterpolator());
+
/**
* Default Constructor.
*/
@@ -679,7 +683,7 @@
{
throw new ConfigurationRuntimeException("File pattern must be defined");
}
- String path = getSubstitutor().replace(pattern);
+ String path = localSubst.replace(pattern);
synchronized (configurationsMap)
{
if (configurationsMap.containsKey(path))
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/XMLConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/XMLConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/java/org/apache/commons/configuration/XMLConfiguration.java Tue Sep 29 23:38:52 2009
@@ -567,6 +567,7 @@
public void clear()
{
super.clear();
+ setRoot(new Node());
document = null;
}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/Logging.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/Logging.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/Logging.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/Logging.java Tue Sep 29 23:38:52 2009
@@ -59,7 +59,7 @@
{
org.apache.log4j.Logger log = org.apache.log4j.Logger.getRootLogger();
log.setLevel(Level.toLevel(level));
- Appender appender = new ConsoleAppender(new PatternLayout("%p - %m%n"), ConsoleAppender.SYSTEM_OUT);
+ Appender appender = new ConsoleAppender(new PatternLayout("%p %l - %m%n"), ConsoleAppender.SYSTEM_OUT);
log.addAppender(appender);
}
}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestDynamicCombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestDynamicCombinedConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestDynamicCombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestDynamicCombinedConfiguration.java Tue Sep 29 23:38:52 2009
@@ -21,12 +21,15 @@
import junit.framework.TestCase;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+import org.apache.commons.lang.text.StrLookup;
public class TestDynamicCombinedConfiguration extends TestCase
{
private static String PATTERN ="${sys:Id}";
private static String PATTERN1 = "target/test-classes/testMultiConfiguration_${sys:Id}.xml";
private static String DEFAULT_FILE = "target/test-classes/testMultiConfiguration_default.xml";
+ private static final File MULTI_TENENT_FILE = new File(
+ "conf/testMultiTenentConfigurationBuilder4.xml");
public void testConfiguration() throws Exception
{
@@ -57,9 +60,186 @@
assertEquals("a\\,b\\,c", config.getString("split/list2"));
}
+ public void testConcurrentGetAndReload() throws Exception
+ {
+ final int threadCount = 5;
+ final int loopCount = 500;
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+
+ assertEquals(config.getString("rowsPerPage"), "50");
+ Thread testThreads[] = new Thread[threadCount];
+ int failures[] = new int[threadCount];
+
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i] = new ReloadThread(config, failures, i, loopCount, false, null, "50");
+ testThreads[i].start();
+ }
+
+ int totalFailures = 0;
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i].join();
+ totalFailures += failures[i];
+ }
+ assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
+ }
+
+ public void testConcurrentGetAndReload2() throws Exception
+ {
+ final int threadCount = 5;
+ final int loopCount = 500;
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+
+ assertEquals(config.getString("rowsPerPage"), "50");
+
+ Thread testThreads[] = new Thread[threadCount];
+ int failures[] = new int[threadCount];
+ System.setProperty("Id", "2002");
+ assertEquals(config.getString("rowsPerPage"), "25");
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i] = new ReloadThread(config, failures, i, loopCount, false, null, "25");
+ testThreads[i].start();
+ }
+
+ int totalFailures = 0;
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i].join();
+ totalFailures += failures[i];
+ }
+ System.getProperties().remove("Id");
+ assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
+ }
+
+ public void testConcurrentGetAndReloadMultipleClients() throws Exception
+ {
+ final int threadCount = 5;
+ final int loopCount = 500;
+ System.getProperties().remove("Id");
+ DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+ factory.setFile(MULTI_TENENT_FILE);
+ CombinedConfiguration config = factory.getConfiguration(true);
+
+ assertEquals(config.getString("rowsPerPage"), "50");
+
+ Thread testThreads[] = new Thread[threadCount];
+ int failures[] = new int[threadCount];
+ String[] ids = new String[] {null, "2002", "3001", "3002", "3003"};
+ String[] expected = new String[] {"50", "25", "15", "25", "50"};
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i] = new ReloadThread(config, failures, i, loopCount, true, ids[i], expected[i]);
+ testThreads[i].start();
+ }
+
+ int totalFailures = 0;
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ testThreads[i].join();
+ totalFailures += failures[i];
+ }
+ System.getProperties().remove("Id");
+ if (totalFailures != 0)
+ {
+ System.out.println("Failures:");
+ for (int i = 0; i < testThreads.length; ++i)
+ {
+ System.out.println("Thread " + i + " " + failures[i]);
+ }
+ }
+ assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
+ }
+
+ private class ReloadThread extends Thread
+ {
+ CombinedConfiguration combined;
+ int[] failures;
+ int index;
+ int count;
+ String expected;
+ String id;
+ boolean useId;
+
+ ReloadThread(CombinedConfiguration config, int[] failures, int index, int count,
+ boolean useId, String id, String expected)
+ {
+ combined = config;
+ this.failures = failures;
+ this.index = index;
+ this.count = count;
+ this.expected = expected;
+ this.id = id;
+ this.useId = useId;
+ }
+ public void run()
+ {
+ failures[index] = 0;
+
+ if (useId)
+ {
+ ThreadLookup.setId(id);
+ }
+ for (int i = 0; i < count; i++)
+ {
+ try
+ {
+ String value = combined.getString("rowsPerPage", null);
+ if (value == null || !value.equals(expected))
+ {
+ ++failures[index];
+ }
+ }
+ catch (Exception ex)
+ {
+ ++failures[index];
+ }
+ }
+ }
+ }
+
private void verify(String key, DynamicCombinedConfiguration config, int rows)
{
System.setProperty("Id", key);
assertTrue(config.getInt("rowsPerPage") == rows);
}
+
+ public static class ThreadLookup extends StrLookup
+ {
+ private static ThreadLocal id = new ThreadLocal();
+
+
+
+ public ThreadLookup()
+ {
+
+ }
+
+ public static void setId(String value)
+ {
+ id.set(value);
+ }
+
+ public String lookup(String key)
+ {
+ if (key == null || !key.equals("Id"))
+ {
+ return null;
+ }
+ String value = System.getProperty("Id");
+ if (value != null)
+ {
+ return value;
+ }
+ return (String)id.get();
+
+ }
+ }
}
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/TestXMLConfiguration.java Tue Sep 29 23:38:52 2009
@@ -639,6 +639,39 @@
}
}
+ public void testReloadingOOM() throws Exception
+ {
+ assertNotNull(conf.getReloadingStrategy());
+ assertTrue(conf.getReloadingStrategy() instanceof InvariantReloadingStrategy);
+ PrintWriter out = null;
+
+ try
+ {
+ out = new PrintWriter(new FileWriter(testSaveConf));
+ out.println("<?xml version=\"1.0\"?><config><test>1</test></config>");
+ out.close();
+ out = null;
+ conf.setFile(testSaveConf);
+ FileAlwaysReloadingStrategy strategy = new FileAlwaysReloadingStrategy();
+ strategy.setRefreshDelay(100);
+ conf.setReloadingStrategy(strategy);
+ conf.load();
+ assertEquals(1, conf.getInt("test"));
+
+ for (int i = 1; i < 50000; ++i)
+ {
+ assertEquals(1, conf.getInt("test"));
+ }
+ }
+ finally
+ {
+ if (out != null)
+ {
+ out.close();
+ }
+ }
+ }
+
/**
* Tests access to tag names with delimiter characters.
*/
@@ -1615,7 +1648,7 @@
for (int i = 0; i < 2000; i++)
{
- assertTrue("Property not found", config.getProperty("test.short") != null);
+ assertTrue("Property not found", config.getProperty("test.short") != null);
}
for (int i = 0; i < testThreads.length; ++i)
Modified: commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java?rev=820124&r1=820123&r2=820124&view=diff
==============================================================================
--- commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java (original)
+++ commons/proper/configuration/branches/CONFIGURATION_390/src/test/org/apache/commons/configuration/reloading/FileRandomReloadingStrategy.java Tue Sep 29 23:38:52 2009
@@ -1,5 +1,8 @@
package org.apache.commons.configuration.reloading;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import java.io.File;
import java.util.Random;
@@ -9,6 +12,10 @@
public class FileRandomReloadingStrategy extends FileChangedReloadingStrategy
{
Random random = new Random();
+
+ /** The Log to use for diagnostic messages */
+ private Log logger = LogFactory.getLog(FileRandomReloadingStrategy.class);
+
/**
* Checks whether a reload is necessary.
*
@@ -16,7 +23,15 @@
*/
public boolean reloadingRequired()
{
- return random.nextBoolean();
+ boolean result = random.nextBoolean();
+ if (result)
+ {
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("File change detected: " + getName());
+ }
+ }
+ return result;
}
/**
@@ -28,4 +43,27 @@
{
return getFile();
}
+
+ private String getName()
+ {
+ return getName(getFile());
+ }
+
+ private String getName(File file)
+ {
+ String name = configuration.getURL().toString();
+ if (name == null)
+ {
+ if (file != null)
+ {
+ name = file.getAbsolutePath();
+ }
+ else
+ {
+ name = "base: " + configuration.getBasePath()
+ + "file: " + configuration.getFileName();
+ }
+ }
+ return name;
+ }
}