Explicitly providing a
CacheManagername in an Ehcache configuration file allows to avoid the "CacheManager with same name already exists in the same VM" error after upgrading to Ehcache version 2.5 and later.
The CacheManager name should be specified in each Ehcache config file via the
nameattribute of the top-level
ehcacheelement, for example:
<ehcache name="http-filter-cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcahce.xsd"> <defaultCache /> </ehcache>This works regardless whether a singleton or multiple instances of CacheManager are created.
Ehcache is a widely used open-source caching solution for enterprise Java applications.
Most known examples, perhaps arguably, would be using Ehcache as a second-level Hibernate cache and the cache implementation in Apache Camel.
Version 2.5 was enhanced with a new feature called Automatic Resource Control. The ARC (finally) allowed to specify heap and disk allocations in bytes rather than in elements (as well as for Off Heap storage).
After upgrading a Java web application to take advantage of the new version, we encountered a problem that manifested in failures of numerous JUnit tests. Launching the web application also started to fail.
Examining log files revealed the following error message:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The application included 2 Ehcache configuration files each containing a default cache definition as well as several other named caches. At first, a suspicion was that the problems were caused by having more than one default cache (each file contains a default cache definition). Since the default caches are unnamed, there might have been a collision. That's however proved to be a totally wrong lead.
Proceeding to examine the source code of
net.sf.ehcache.CacheManagerclass, we came across this javadoc comment in class constructors:
Looking further into the source code and stepping in with the debugger, we discovered that CacheManager now maintains a static
Map<String, CacheManager>class variable to store every instance of the class created in the JVM using the name specified in a configuration as the key (the map is named
CACHE_MANAGERS_MAPas of version
All constructors and the factory methods utilize the map to return a CacheManager object according to the specs. The CacheManager provides two kinds of instantiation modes: creating a new instance on each call or returning an existing object (singleton). (More on CacheManager creation modes can be found on a Ehcache website).
Regardless of the creation mode, i.e. instance or singleton, the CacheManager name must be unique.
Surprisingly, considering that the change is quite well documented, the Ehcache documentation does not spell out, at least not readily, how to assign a name to a
The answer was found in the ehcache.xsd schema that specifies the optional
nameattribute for the
<xs:schema> <xs:element name="ehcache"> <xs:complexType> <xs:attribute name="name" use="optional"/> <xs:sequence> <xs:element maxOccurs="1" minOccurs="0" ref="diskStore"/> ... </xs:sequence> ...When the
nameattribute is specified for the the top-level
CacheManagerconstructor will use its value as the name for the CacheManger instance and as the key when registering the object in the static
CACHE_MANAGERS_MAPmap. Otherwise, i.e. when the name attribute is omitted, CacheManager will use a default value,
__DEFAULT__, as the name. If the app is designed to use a single ehcache configuration, it will not cause any trouble. However, there are cases when it's preferable to use multiple cache configuration files. In which case it will result in the error when the name attribute is not used.
To avoid the problem, each Ehcache configuration should specify a name. The fragment from a configuration file below is an example:
<ehcache name="http-filter-cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocaton="ehcache.xsd"> <!-- CacheManager configuration (omitted from the sample) /> </ehcache>And in conclusion, a friendly suggestion to the Ehcache development team: maybe the name attribute should be made mandatory rather than optional to avoid the problem described in this post.