Author: tv Date: Sat Jan 30 15:24:32 2016 New Revision: 1727713 URL: http://svn.apache.org/viewvc?rev=1727713&view=rev Log: Attempt to fix JCS-116 : CompositeCacheManager is thread-hostile
Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java commons/proper/jcs/trunk/src/changes/changes.xml Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java?rev=1727713&r1=1727712&r2=1727713&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java Sat Jan 30 15:24:32 2016 @@ -19,10 +19,7 @@ package org.apache.commons.jcs.engine.co * under the License. */ -import java.io.FileInputStream; -import java.io.IOException; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.StringTokenizer; @@ -56,26 +53,26 @@ public class CompositeCacheConfigurator /** The logger */ private static final Log log = LogFactory.getLog( CompositeCacheConfigurator.class ); - /** default region prefix */ - static final String DEFAULT_REGION = "jcs.default"; + /** The prefix of relevant system properties */ + protected static final String SYSTEM_PROPERTY_KEY_PREFIX = "jcs"; /** normal region prefix */ - static final String REGION_PREFIX = "jcs.region."; + protected static final String REGION_PREFIX = "jcs.region."; /** system region prefix. might not be used */ - static final String SYSTEM_REGION_PREFIX = "jcs.system."; + protected static final String SYSTEM_REGION_PREFIX = "jcs.system."; /** auxiliary prefix */ - static final String AUXILIARY_PREFIX = "jcs.auxiliary."; + protected static final String AUXILIARY_PREFIX = "jcs.auxiliary."; /** .attributes */ - static final String ATTRIBUTE_PREFIX = ".attributes"; + protected static final String ATTRIBUTE_PREFIX = ".attributes"; /** .cacheattributes */ - static final String CACHE_ATTRIBUTE_PREFIX = ".cacheattributes"; + protected static final String CACHE_ATTRIBUTE_PREFIX = ".cacheattributes"; /** .elementattributes */ - static final String ELEMENT_ATTRIBUTE_PREFIX = ".elementattributes"; + protected static final String ELEMENT_ATTRIBUTE_PREFIX = ".elementattributes"; /** * jcs.auxiliary.NAME.keymatcher=CLASSNAME @@ -84,171 +81,34 @@ public class CompositeCacheConfigurator */ public static final String KEY_MATCHER_PREFIX = ".keymatcher"; - /** Can't operate on the interface. */ - private final CompositeCacheManager compositeCacheManager; - /** * Constructor for the CompositeCacheConfigurator object - *<p> - * @param ccMgr - */ - public CompositeCacheConfigurator( CompositeCacheManager ccMgr ) - { - this.compositeCacheManager = ccMgr; - } - - /** - * Configure cached for file name. - * <p> - * This is only used for testing. The manager handles the translation of a file into a - * properties object. - * <p> - * @param configFileName - */ - protected void doConfigure( String configFileName ) - { - Properties props = new Properties(); - FileInputStream istream = null; - - try - { - istream = new FileInputStream( configFileName ); - props.load( istream ); - } - catch ( IOException e ) - { - log.error( "Could not read configuration file, ignored: " + configFileName, e ); - return; - } - finally - { - if (istream != null) - { - try - { - istream.close(); - } - catch (IOException e) - { - log.error( "Could not close configuration file " + configFileName, e ); - } - } - } - - // If we reach here, then the config file is all right. - doConfigure( props ); - } - - /** - * Configure cache for properties object. - * <p> - * This method proceeds in several steps: - * <ul> - * <li>Store props for use by non configured caches. - * <li>Set default value list - * <li>Set default cache attr - * <li>Set default element attr - * <li>Setup system caches to be used - * <li>Setup preconfigured caches - * </ul> - * @param properties - */ - public void doConfigure( Properties properties ) - { - long start = System.currentTimeMillis(); - - // store props for use by non configured caches - compositeCacheManager.setConfigurationProperties( properties ); - - // set default value list - setDefaultAuxValues( properties ); - - // set default cache attr - setDefaultCompositeCacheAttributes( properties ); - - // set default element attr - setDefaultElementAttributes( properties ); - - // set up system caches to be used by non system caches - // need to make sure there is no circularity of reference - parseSystemRegions( properties ); - - // setup preconfigured caches - parseRegions( properties ); - - long end = System.currentTimeMillis(); - if ( log.isInfoEnabled() ) - { - log.info( "Finished configuration in " + ( end - start ) + " ms." ); - } - - } - - /** - * Set the default aux list for new caches. - * <p> - * @param props */ - protected void setDefaultAuxValues( Properties props ) + public CompositeCacheConfigurator() { - String value = OptionConverter.findAndSubst( DEFAULT_REGION, props ); - compositeCacheManager.setDefaultAuxValues(value); - - if ( log.isInfoEnabled() ) - { - log.info( "Setting default auxiliaries to " + value ); - } - } - - /** - * Set the default CompositeCacheAttributes for new caches. - *<p> - * @param props - */ - protected void setDefaultCompositeCacheAttributes( Properties props ) - { - ICompositeCacheAttributes icca = parseCompositeCacheAttributes( props, "", - CompositeCacheConfigurator.DEFAULT_REGION ); - compositeCacheManager.setDefaultCacheAttributes( icca ); - - log.info( "setting defaultCompositeCacheAttributes to " + icca ); - } - - /** - * Set the default ElementAttributes for new caches. - *<p> - * @param props - */ - protected void setDefaultElementAttributes( Properties props ) - { - IElementAttributes iea = parseElementAttributes( props, "", CompositeCacheConfigurator.DEFAULT_REGION ); - compositeCacheManager.setDefaultElementAttributes( iea ); - - log.info( "setting defaultElementAttributes to " + iea ); + // empty } /** * Create caches used internally. System status gives them creation priority. *<p> - * @param props + * @param props Configuration properties + * @param ccm Cache hub */ - protected void parseSystemRegions( Properties props ) + protected void parseSystemRegions( Properties props, CompositeCacheManager ccm ) { - Enumeration<?> en = props.propertyNames(); - while ( en.hasMoreElements() ) + for (String key : props.stringPropertyNames() ) { - String key = (String) en.nextElement(); if ( key.startsWith( SYSTEM_REGION_PREFIX ) && key.indexOf( "attributes" ) == -1 ) { String regionName = key.substring( SYSTEM_REGION_PREFIX.length() ); - String value = OptionConverter.findAndSubst( key, props ); + String auxiliaries = OptionConverter.findAndSubst( key, props ); ICache<?, ?> cache; synchronized ( regionName ) { - cache = parseRegion( props, regionName, value, null, SYSTEM_REGION_PREFIX ); + cache = parseRegion( props, ccm, regionName, auxiliaries, null, SYSTEM_REGION_PREFIX ); } - - compositeCacheManager.addCache( regionName, cache ); + ccm.addCache( regionName, cache ); } } } @@ -256,29 +116,26 @@ public class CompositeCacheConfigurator /** * Parse region elements. *<p> - * @param props + * @param props Configuration properties + * @param ccm Cache hub */ - protected void parseRegions( Properties props ) + protected void parseRegions( Properties props, CompositeCacheManager ccm ) { List<String> regionNames = new ArrayList<String>(); - Enumeration<?> en = props.propertyNames(); - while ( en.hasMoreElements() ) + for (String key : props.stringPropertyNames() ) { - String key = (String) en.nextElement(); if ( key.startsWith( REGION_PREFIX ) && key.indexOf( "attributes" ) == -1 ) { String regionName = key.substring( REGION_PREFIX.length() ); - regionNames.add( regionName ); - - String auxiliaryList = OptionConverter.findAndSubst( key, props ); + String auxiliaries = OptionConverter.findAndSubst( key, props ); ICache<?, ?> cache; synchronized ( regionName ) { - cache = parseRegion( props, regionName, auxiliaryList ); + cache = parseRegion( props, ccm, regionName, auxiliaries ); } - compositeCacheManager.addCache( regionName, cache ); + ccm.addCache( regionName, cache ); } } @@ -291,15 +148,17 @@ public class CompositeCacheConfigurator /** * Create cache region. *<p> - * @param props - * @param regName - * @param value + * @param props Configuration properties + * @param ccm Cache hub + * @param regName Name of the cache region + * @param auxiliaries Comma separated list of auxiliaries + * * @return CompositeCache */ protected <K, V> CompositeCache<K, V> parseRegion( - Properties props, String regName, String value ) + Properties props, CompositeCacheManager ccm, String regName, String auxiliaries ) { - return parseRegion( props, regName, value, null, REGION_PREFIX ); + return parseRegion( props, ccm, regName, auxiliaries, null, REGION_PREFIX ); } /** @@ -307,69 +166,76 @@ public class CompositeCacheConfigurator * <p> * This method tells the other parse method the name of the region prefix. *<p> - * @param props - * @param regName - * @param value - * @param cca + * @param props Configuration properties + * @param ccm Cache hub + * @param regName Name of the cache region + * @param auxiliaries Comma separated list of auxiliaries + * @param cca Cache configuration + * * @return CompositeCache */ protected <K, V> CompositeCache<K, V> parseRegion( - Properties props, String regName, String value, ICompositeCacheAttributes cca ) + Properties props, CompositeCacheManager ccm, String regName, String auxiliaries, + ICompositeCacheAttributes cca ) { - return parseRegion( props, regName, value, cca, REGION_PREFIX ); + return parseRegion( props, ccm, regName, auxiliaries, cca, REGION_PREFIX ); } /** * Get all the properties for a region and configure its cache. *<p> - * @param props - * @param regName - * @param value - * @param cca - * @param regionPrefix + * @param props Configuration properties + * @param ccm Cache hub + * @param regName Name of the cache region + * @param auxiliaries Comma separated list of auxiliaries + * @param cca Cache configuration + * @param regionPrefix Prefix for the region + * * @return CompositeCache */ protected <K, V> CompositeCache<K, V> parseRegion( - Properties props, String regName, String value, + Properties props, CompositeCacheManager ccm, String regName, String auxiliaries, ICompositeCacheAttributes cca, String regionPrefix ) { // First, create or get the cache and element attributes, and create // the cache. - IElementAttributes ea = parseElementAttributes( props, regName, regionPrefix ); + IElementAttributes ea = parseElementAttributes( props, regName, + ccm.getDefaultElementAttributes(), regionPrefix ); CompositeCache<K, V> cache = ( cca == null ) - ? new CompositeCache<K, V>( parseCompositeCacheAttributes( props, regName, regionPrefix ), ea ) + ? new CompositeCache<K, V>( parseCompositeCacheAttributes( props, regName, + ccm.getDefaultCacheAttributes(), regionPrefix ), ea ) : new CompositeCache<K, V>( cca, ea ); // Inject scheduler service - cache.setScheduledExecutorService(compositeCacheManager.getScheduledExecutorService()); + cache.setScheduledExecutorService(ccm.getScheduledExecutorService()); // Inject element event queue - cache.setElementEventQueue(compositeCacheManager.getElementEventQueue()); + cache.setElementEventQueue(ccm.getElementEventQueue()); if (cache.getMemoryCache() instanceof IRequireScheduler) { ((IRequireScheduler)cache.getMemoryCache()).setScheduledExecutorService( - compositeCacheManager.getScheduledExecutorService()); + ccm.getScheduledExecutorService()); } - if (value != null) + if (auxiliaries != null) { // Next, create the auxiliaries for the new cache List<AuxiliaryCache<K, V>> auxList = new ArrayList<AuxiliaryCache<K, V>>(); if ( log.isDebugEnabled() ) { - log.debug( "Parsing region name '" + regName + "', value '" + value + "'" ); + log.debug( "Parsing region name '" + regName + "', value '" + auxiliaries + "'" ); } // We must skip over ',' but not white space - StringTokenizer st = new StringTokenizer( value, "," ); + StringTokenizer st = new StringTokenizer( auxiliaries, "," ); // If value is not in the form ", appender.." or "", then we should set // the priority of the category. - if ( !( value.startsWith( "," ) || value.equals( "" ) ) ) + if ( !( auxiliaries.startsWith( "," ) || auxiliaries.equals( "" ) ) ) { // just to be on the safe side... if ( !st.hasMoreTokens() ) @@ -389,14 +255,14 @@ public class CompositeCacheConfigurator } log.debug( "Parsing auxiliary named \"" + auxName + "\"." ); - auxCache = parseAuxiliary( props, auxName, regName ); + auxCache = parseAuxiliary( props, ccm, auxName, regName ); if ( auxCache != null ) { if (auxCache instanceof IRequireScheduler) { - ((IRequireScheduler)auxCache).setScheduledExecutorService( - compositeCacheManager.getScheduledExecutorService()); + ((IRequireScheduler) auxCache).setScheduledExecutorService( + ccm.getScheduledExecutorService()); } auxList.add( auxCache ); @@ -416,25 +282,30 @@ public class CompositeCacheConfigurator /** * Get an ICompositeCacheAttributes for the listed region. *<p> - * @param props - * @param regName + * @param props Configuration properties + * @param regName the region name + * @param defaultCCAttr the default cache attributes + * * @return ICompositeCacheAttributes */ - protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props, String regName ) + protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props, + String regName, ICompositeCacheAttributes defaultCCAttr ) { - return parseCompositeCacheAttributes( props, regName, REGION_PREFIX ); + return parseCompositeCacheAttributes( props, regName, defaultCCAttr, REGION_PREFIX ); } /** * Get the main attributes for a region. *<p> - * @param props - * @param regName - * @param regionPrefix + * @param props Configuration properties + * @param regName the region name + * @param defaultCCAttr the default cache attributes + * @param regionPrefix the region prefix + * * @return ICompositeCacheAttributes */ - protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props, String regName, - String regionPrefix ) + protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props, + String regName, ICompositeCacheAttributes defaultCCAttr, String regionPrefix ) { ICompositeCacheAttributes ccAttr; @@ -452,8 +323,7 @@ public class CompositeCacheConfigurator + "], using default class." ); } - ICompositeCacheAttributes ccAttr2 = compositeCacheManager.getDefaultCacheAttributes(); - ccAttr = ccAttr2.clone(); + ccAttr = defaultCCAttr; } if ( log.isDebugEnabled() ) @@ -477,12 +347,15 @@ public class CompositeCacheConfigurator /** * Create the element attributes from the properties object for a cache region. *<p> - * @param props - * @param regName - * @param regionPrefix + * @param props Configuration properties + * @param regName the region name + * @param defaultEAttr the default element attributes + * @param regionPrefix the region prefix + * * @return IElementAttributes */ - protected IElementAttributes parseElementAttributes( Properties props, String regName, String regionPrefix ) + protected IElementAttributes parseElementAttributes( Properties props, String regName, + IElementAttributes defaultEAttr, String regionPrefix ) { IElementAttributes eAttr; @@ -498,8 +371,7 @@ public class CompositeCacheConfigurator log.info( "No special ElementAttribute class defined for key [" + attrName + "], using default class." ); } - IElementAttributes eAttr2 = compositeCacheManager.getDefaultElementAttributes(); - eAttr = eAttr2.clone(); + eAttr = defaultEAttr; } if ( log.isDebugEnabled() ) @@ -524,11 +396,13 @@ public class CompositeCacheConfigurator * Get an aux cache for the listed aux for a region. *<p> * @param props the configuration properties + * @param ccm Cache hub * @param auxName the name of the auxiliary cache * @param regName the name of the region. * @return AuxiliaryCache */ - protected <K, V> AuxiliaryCache<K, V> parseAuxiliary( Properties props, String auxName, String regName ) + protected <K, V> AuxiliaryCache<K, V> parseAuxiliary( Properties props, CompositeCacheManager ccm, + String auxName, String regName ) { if ( log.isDebugEnabled() ) { @@ -537,12 +411,12 @@ public class CompositeCacheConfigurator // GET CACHE @SuppressWarnings("unchecked") // Common map for all caches - AuxiliaryCache<K, V> auxCache = (AuxiliaryCache<K, V>)compositeCacheManager.getAuxiliaryCache(auxName, regName); + AuxiliaryCache<K, V> auxCache = (AuxiliaryCache<K, V>) ccm.getAuxiliaryCache(auxName, regName); if (auxCache == null) { // GET FACTORY - AuxiliaryCacheFactory auxFac = compositeCacheManager.registryFacGet( auxName ); + AuxiliaryCacheFactory auxFac = ccm.registryFacGet( auxName ); if ( auxFac == null ) { // auxFactory was not previously initialized. @@ -558,16 +432,15 @@ public class CompositeCacheConfigurator if ( auxFac instanceof IRequireScheduler) { - ((IRequireScheduler)auxFac).setScheduledExecutorService(compositeCacheManager.getScheduledExecutorService()); + ((IRequireScheduler)auxFac).setScheduledExecutorService(ccm.getScheduledExecutorService()); } auxFac.initialize(); - - compositeCacheManager.registryFacPut( auxFac ); + ccm.registryFacPut( auxFac ); } // GET ATTRIBUTES - AuxiliaryCacheAttributes auxAttr = compositeCacheManager.registryAttrGet( auxName ); + AuxiliaryCacheAttributes auxAttr = ccm.registryAttrGet( auxName ); String attrName = AUXILIARY_PREFIX + auxName + ATTRIBUTE_PREFIX; if ( auxAttr == null ) { @@ -580,7 +453,7 @@ public class CompositeCacheConfigurator return null; } auxAttr.setName( auxName ); - compositeCacheManager.registryAttrPut( auxAttr ); + ccm.registryAttrPut( auxAttr ); } auxAttr = auxAttr.clone(); @@ -604,10 +477,12 @@ public class CompositeCacheConfigurator String auxPrefix = AUXILIARY_PREFIX + auxName; // CONFIGURE THE EVENT LOGGER - ICacheEventLogger cacheEventLogger = AuxiliaryCacheConfigurator.parseCacheEventLogger( props, auxPrefix ); + ICacheEventLogger cacheEventLogger = + AuxiliaryCacheConfigurator.parseCacheEventLogger( props, auxPrefix ); // CONFIGURE THE ELEMENT SERIALIZER - IElementSerializer elementSerializer = AuxiliaryCacheConfigurator.parseElementSerializer( props, auxPrefix ); + IElementSerializer elementSerializer = + AuxiliaryCacheConfigurator.parseElementSerializer( props, auxPrefix ); // CONFIGURE THE KEYMATCHER //IKeyMatcher keyMatcher = parseKeyMatcher( props, auxPrefix ); @@ -619,7 +494,7 @@ public class CompositeCacheConfigurator // before the auxiliary is created. try { - auxCache = auxFac.createCache( auxAttr, compositeCacheManager, cacheEventLogger, elementSerializer ); + auxCache = auxFac.createCache( auxAttr, ccm, cacheEventLogger, elementSerializer ); } catch (Exception e) { @@ -627,20 +502,42 @@ public class CompositeCacheConfigurator return null; } - compositeCacheManager.addAuxiliaryCache(auxName, regName, auxCache); + ccm.addAuxiliaryCache(auxName, regName, auxCache); } return auxCache; } /** + * Any property values will be replaced with system property values that match the key. + * <p> + * @param props + */ + protected static void overrideWithSystemProperties( Properties props ) + { + // override any setting with values from the system properties. + Properties sysProps = System.getProperties(); + for (String key : sysProps.stringPropertyNames()) + { + if ( key.startsWith( SYSTEM_PROPERTY_KEY_PREFIX ) ) + { + if ( log.isInfoEnabled() ) + { + log.info( "Using system property [[" + key + "] [" + sysProps.getProperty( key ) + "]]" ); + } + props.setProperty( key, sysProps.getProperty( key ) ); + } + } + } + + /** * Creates a custom key matcher if one is defined. Else, it uses the default. * <p> * @param props * @param auxPrefix - ex. AUXILIARY_PREFIX + auxName * @return IKeyMatcher */ - public static <K> IKeyMatcher<K> parseKeyMatcher( Properties props, String auxPrefix ) + protected <K> IKeyMatcher<K> parseKeyMatcher( Properties props, String auxPrefix ) { // auxFactory was not previously initialized. Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java?rev=1727713&r1=1727712&r2=1727713&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java Sat Jan 30 15:24:32 2016 @@ -24,14 +24,13 @@ import java.io.InputStream; import java.lang.management.ManagementFactory; import java.security.AccessControlException; import java.util.ArrayList; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Properties; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import javax.management.MBeanServer; @@ -57,6 +56,7 @@ import org.apache.commons.jcs.engine.con import org.apache.commons.jcs.engine.control.event.behavior.IElementEventQueue; import org.apache.commons.jcs.engine.stats.CacheStats; import org.apache.commons.jcs.engine.stats.behavior.ICacheStats; +import org.apache.commons.jcs.utils.config.OptionConverter; import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory; import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager; import org.apache.commons.logging.Log; @@ -79,15 +79,18 @@ public class CompositeCacheManager /** JMX object name */ public static final String JMX_OBJECT_NAME = "org.apache.commons.jcs:type=JCSAdminBean"; + /** default region prefix */ + private static final String DEFAULT_REGION = "jcs.default"; + /** Caches managed by this cache manager */ private final ConcurrentMap<String, ICache<?, ?>> caches = new ConcurrentHashMap<String, ICache<?, ?>>(); /** Lock for initialization of caches */ - private ReentrantLock cacheLock = new ReentrantLock(); + private final ReentrantLock cacheLock = new ReentrantLock(); /** Number of clients accessing this cache manager */ - private int clients; + private final AtomicInteger clients = new AtomicInteger(0); /** Default cache attributes for this cache manager */ private ICompositeCacheAttributes defaultCacheAttr = new CompositeCacheAttributes(); @@ -97,15 +100,15 @@ public class CompositeCacheManager /** Used to keep track of configured auxiliaries */ private final ConcurrentMap<String, AuxiliaryCacheFactory> auxiliaryFactoryRegistry = - new ConcurrentHashMap<String, AuxiliaryCacheFactory>( 11 ); + new ConcurrentHashMap<String, AuxiliaryCacheFactory>( ); /** Used to keep track of attributes for auxiliaries. */ private final ConcurrentMap<String, AuxiliaryCacheAttributes> auxiliaryAttributeRegistry = - new ConcurrentHashMap<String, AuxiliaryCacheAttributes>( 11 ); + new ConcurrentHashMap<String, AuxiliaryCacheAttributes>( ); /** Used to keep track of configured auxiliaries */ private final ConcurrentMap<String, AuxiliaryCache<?, ?>> auxiliaryCaches = - new ConcurrentHashMap<String, AuxiliaryCache<?, ?>>( 11 ); + new ConcurrentHashMap<String, AuxiliaryCache<?, ?>>( ); /** Properties with which this manager was configured. This is exposed for other managers. */ private Properties configurationProperties; @@ -116,9 +119,6 @@ public class CompositeCacheManager /** The Singleton Instance */ private static CompositeCacheManager instance; - /** The prefix of relevant system properties */ - private static final String SYSTEM_PROPERTY_KEY_PREFIX = "jcs"; - /** Should we use system property substitutions. */ private static final boolean DEFAULT_USE_SYSTEM_PROPERTIES = true; @@ -190,7 +190,7 @@ public class CompositeCacheManager instance.configure( propsFilename ); } - instance.incrementClients(); + instance.clients.incrementAndGet(); return instance; } @@ -218,7 +218,7 @@ public class CompositeCacheManager instance.initialize(); } - instance.incrementClients(); + instance.clients.incrementAndGet(); return instance; } @@ -436,50 +436,23 @@ public class CompositeCacheManager } if ( useSystemProperties ) { - overrideWithSystemProperties( props ); + CompositeCacheConfigurator.overrideWithSystemProperties( props ); } doConfigure( props ); } /** - * Any property values will be replaced with system property values that match the key. - * <p> - * TODO move to a utility. - * <p> - * @param props - */ - private static void overrideWithSystemProperties( Properties props ) - { - // override any setting with values from the system properties. - Properties sysProps = System.getProperties(); - Set<Object> keys = sysProps.keySet(); - Iterator<Object> keyIt = keys.iterator(); - while ( keyIt.hasNext() ) - { - String key = (String) keyIt.next(); - if ( key.startsWith( SYSTEM_PROPERTY_KEY_PREFIX ) ) - { - if ( log.isInfoEnabled() ) - { - log.info( "Using system property [[" + key + "] [" + sysProps.getProperty( key ) + "]]" ); - } - props.setProperty( key, sysProps.getProperty( key ) ); - } - } - } - - /** * Configure the cache using the supplied properties. * <p> - * @param props assumed not null + * @param properties assumed not null */ - private void doConfigure( Properties props ) + private void doConfigure( Properties properties ) { // We will expose this for managers that need raw properties. - this.configurationProperties = props; + this.configurationProperties = properties; // set the props value and then configure the ThreadPoolManager - ThreadPoolManager.setProps( props ); + ThreadPoolManager.setProps( properties ); ThreadPoolManager poolMgr = ThreadPoolManager.getInstance(); if ( log.isDebugEnabled() ) { @@ -487,9 +460,40 @@ public class CompositeCacheManager } // configure the cache - CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( this ); + CompositeCacheConfigurator configurator = new CompositeCacheConfigurator(); + + long start = System.currentTimeMillis(); + + // set default value list + this.defaultAuxValues = OptionConverter.findAndSubst( CompositeCacheManager.DEFAULT_REGION, + properties ); + + log.info( "Setting default auxiliaries to " + this.defaultAuxValues ); + + // set default cache attr + this.defaultCacheAttr = configurator.parseCompositeCacheAttributes( properties, "", + new CompositeCacheAttributes(), DEFAULT_REGION ); + + log.info( "setting defaultCompositeCacheAttributes to " + this.defaultCacheAttr ); + + // set default element attr + this.defaultElementAttr = configurator.parseElementAttributes( properties, "", + new ElementAttributes(), DEFAULT_REGION ); + + log.info( "setting defaultElementAttributes to " + this.defaultElementAttr ); - configurator.doConfigure( props ); + // set up system caches to be used by non system caches + // need to make sure there is no circularity of reference + configurator.parseSystemRegions( properties, this ); + + // setup preconfigured caches + configurator.parseRegions( properties, this ); + + long end = System.currentTimeMillis(); + if ( log.isInfoEnabled() ) + { + log.info( "Finished configuration in " + ( end - start ) + " ms." ); + } isConfigured = true; } @@ -505,26 +509,6 @@ public class CompositeCacheManager } /** - * Sets the defaultCacheAttributes attribute of the CacheHub object - * <p> - * @param icca The new defaultCacheAttributes value - */ - public void setDefaultCacheAttributes( ICompositeCacheAttributes icca ) - { - this.defaultCacheAttr = icca; - } - - /** - * Sets the defaultElementAttributes attribute of the CacheHub object - * <p> - * @param iea The new defaultElementAttributes value - */ - public void setDefaultElementAttributes( IElementAttributes iea ) - { - this.defaultElementAttr = iea; - } - - /** * Gets the defaultElementAttributes attribute of the CacheHub object * <p> * @return The defaultElementAttributes value @@ -541,7 +525,7 @@ public class CompositeCacheManager * @return CompositeCache -- the cache region controller */ @Override - public <K, V> CompositeCache<K, V> getCache( String cacheName ) + public <K, V> CompositeCache<K, V> getCache( String cacheName ) { return getCache( cacheName, this.defaultCacheAttr.clone() ); } @@ -622,9 +606,9 @@ public class CompositeCacheManager { cattr.setCacheName( cattr.getCacheName() ); - CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( this ); + CompositeCacheConfigurator configurator = new CompositeCacheConfigurator(); - cache = configurator.parseRegion( this.getConfigurationProperties(), cattr.getCacheName(), + cache = configurator.parseRegion( this.getConfigurationProperties(), this, cattr.getCacheName(), this.defaultAuxValues, cattr ); caches.put( cattr.getCacheName(), cache ); @@ -687,6 +671,8 @@ public class CompositeCacheManager { observer.shutdown(); } + + shutdownObservers.clear(); } // Unregister JMX bean @@ -741,12 +727,6 @@ public class CompositeCacheManager } /** */ - private void incrementClients() - { - clients++; - } - - /** */ public void release() { release( false ); @@ -760,7 +740,7 @@ public class CompositeCacheManager synchronized ( CompositeCacheManager.class ) { // Wait until called by the last client - if ( --clients > 0 ) + if ( clients.decrementAndGet() > 0 ) { if ( log.isDebugEnabled() ) { @@ -804,14 +784,6 @@ public class CompositeCacheManager } /** - * @return ICompositeCacheAttributes - */ - public ICompositeCacheAttributes getDefaultCattr() - { - return this.defaultCacheAttr; - } - - /** * @param auxFac */ public void registryFacPut( AuxiliaryCacheFactory auxFac ) @@ -886,14 +858,6 @@ public class CompositeCacheManager } /** - * @param defaultAuxValues the defaultAuxValues to set - */ - public void setDefaultAuxValues(String defaultAuxValues) - { - this.defaultAuxValues = defaultAuxValues; - } - - /** * Gets stats for debugging. This calls gets statistics and then puts all the results in a * string. This returns data for all regions. * <p> @@ -974,16 +938,6 @@ public class CompositeCacheManager /** * This is exposed so other manager can get access to the props. * <p> - * @param props - */ - void setConfigurationProperties( Properties props ) - { - this.configurationProperties = props; - } - - /** - * This is exposed so other manager can get access to the props. - * <p> * @return the configurationProperties */ @Override @@ -1008,7 +962,8 @@ public class CompositeCacheManager return isConfigured; } - public void setJmxName(final String name) { + public void setJmxName(final String name) + { if (isJMXRegistered) { throw new IllegalStateException("Too late, MBean registration is done"); Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java?rev=1727713&r1=1727712&r2=1727713&view=diff ============================================================================== --- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java (original) +++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java Sat Jan 30 15:24:32 2016 @@ -19,7 +19,10 @@ package org.apache.commons.jcs.engine.co * under the License. */ +import java.util.Properties; + import junit.framework.TestCase; + import org.apache.commons.jcs.auxiliary.AuxiliaryCache; import org.apache.commons.jcs.auxiliary.AuxiliaryCacheConfigurator; import org.apache.commons.jcs.auxiliary.MockAuxiliaryCache; @@ -27,8 +30,6 @@ import org.apache.commons.jcs.auxiliary. import org.apache.commons.jcs.auxiliary.MockAuxiliaryCacheFactory; import org.apache.commons.jcs.engine.logging.MockCacheEventLogger; -import java.util.Properties; - /** Unit tests for the configurator. */ public class CompositeCacheConfiguratorUnitTest extends TestCase @@ -42,7 +43,7 @@ public class CompositeCacheConfiguratorU String regionName = "MyRegion"; String auxName = "MockAux"; - String auxPrefix = "jcs.auxiliary." + auxName; + String auxPrefix = CompositeCacheConfigurator.AUXILIARY_PREFIX + auxName; String auxiliaryClassName = MockAuxiliaryCacheFactory.class.getName(); String eventLoggerClassName = MockCacheEventLogger.class.getName(); String auxiliaryAttributeClassName = MockAuxiliaryCacheAttributes.class.getName(); @@ -55,11 +56,10 @@ public class CompositeCacheConfiguratorU // System.out.print( props ); CompositeCacheManager manager = CompositeCacheManager.getUnconfiguredInstance(); - - CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( manager ); + CompositeCacheConfigurator configurator = new CompositeCacheConfigurator(); // DO WORK - AuxiliaryCache<String, String> aux = configurator.parseAuxiliary( props, auxName, regionName ); + AuxiliaryCache<String, String> aux = configurator.parseAuxiliary( props, manager, auxName, regionName ); MockAuxiliaryCache<String, String> result = (MockAuxiliaryCache<String, String>)aux; // VERIFY Modified: commons/proper/jcs/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/src/changes/changes.xml?rev=1727713&r1=1727712&r2=1727713&view=diff ============================================================================== --- commons/proper/jcs/trunk/src/changes/changes.xml (original) +++ commons/proper/jcs/trunk/src/changes/changes.xml Sat Jan 30 15:24:32 2016 @@ -20,6 +20,9 @@ </properties> <body> <release version="2.0" date="unreleased" description="JDK 1.6 based major release"> + <action issue="JCS-116" dev="tv" type="fix" due-to="Sebb"> + Fix: CompositeCacheManager is thread-hostile + </action> <action issue="JCS-158" dev="tv" type="fix" due-to="Wiktor Niesiobedzki"> Fix NullPointerException in IndexedDiskCache.addToRecycleBin(...) </action>