ehcache / ehcache-jcache Goto Github PK
View Code? Open in Web Editor NEWThe Ehcache 2.x implementation of JSR107 (JCACHE)
License: Other
The Ehcache 2.x implementation of JSR107 (JCACHE)
License: Other
Hi,
using following artefacts
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>jcache</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jsr107.ri</groupId>
<artifactId>cache-annotations-ri-cdi</artifactId>
<version>1.0.0</version>
</dependency>
I get the following Exception when returning null from an
@CachePut(cacheName = CacheNames.USER_DAO_CACHE)
java.lang.IllegalArgumentException: cacheValueParameter cannot be null
2014-05-07 15:24:11.669231+00:00 app web.1 - - at org.jsr107.ri.annotations.CachePutMethodDetails.(CachePutMethodDetails.java:49)
2014-05-07 15:24:11.669233+00:00 app web.1 - - at org.jsr107.ri.annotations.AbstractCacheLookupUtil.createCachePutMethodDetails(AbstractCacheLookupUtil.java:332)
2014-05-07 15:24:11.669235+00:00 app web.1 - - at org.jsr107.ri.annotations.AbstractCacheLookupUtil.getMethodDetails(AbstractCacheLookupUtil.java:193)
2014-05-07 15:24:11.669236+00:00 app web.1 - - at org.jsr107.ri.annotations.AbstractCacheLookupUtil.getCacheKeyInvocationContext(AbstractCacheLookupUtil.java:72)
2014-05-07 15:24:11.669238+00:00 app web.1 - - at org.jsr107.ri.annotations.AbstractCachePutInterceptor.cachePut(AbstractCachePutInterceptor.java:48)
2014-05-07 15:24:11.669239+00:00 app web.1 - - at org.jsr107.ri.annotations.cdi.CachePutInterceptor.cachePut(CachePutInterceptor.java:51)
2014-05-07 15:24:11.669241+00:00 app web.1 - - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2014-05-07 15:24:11.669243+00:00 app web.1 - - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
2014-05-07 15:24:11.669244+00:00 app web.1 - - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2014-05-07 15:24:11.669246+00:00 app web.1 - - at java.lang.reflect.Method.invoke(Method.java:606)
2014-05-07 15:24:11.669247+00:00 app web.1 - - at org.jboss.weld.interceptor.proxy.SimpleMethodInvocation.invoke(SimpleMethodInvocation.java:30)
2014-05-07 15:24:11.669249+00:00 app web.1 - - at org.jboss.weld.interceptor.proxy.SimpleInterceptionChain.invokeNextInterceptor(SimpleInterceptionChain.java:69)
2014-05-07 15:24:11.669250+00:00 app web.1 - - at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:112)
2014-05-07 15:24:11.669252+00:00 app web.1 - - at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:88)
2014-05-07 15:24:11.669254+00:00 app web.1 - - at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:55)
2014-05-07 15:24:11.669255+00:00 app web.1 - - at org.remedia.foxydeal.clickserver.persistence.domain.UserDAO$Proxy$_$$WeldSubclass.get(UserDAO$Proxy$$$_WeldSubclass.java)
I like to externalize my ehcache.xml, so when I deploy to different environments (dev = no replication, prod = replication) I do not want have to repackage my wars. Is there another option besides classpath loading?
Based on issue #30, we may want to read things like capacity control (and tiering?) from the defaultCache
and merge it in with the Configuration
provided to javax.cache.CacheManager#createCache
.
Ehcache certainly requires a capacity to be set on the Cache
, which now defaults to JCacheManager. DEFAULT_SIZE
. There may well be other setting we may want to "copy" from there...
Now I find that capacity set this way seems to only address an implementation issue (i.e. Ehcache requiring this setting), but I don't see how one would actually configure this one single value for all programmatically configured javax.cache.Cache
to anything meaningful...
Thoughts?
Reported here:
https://jira.terracotta.org/jira/browse/EHC-894
There is a workaround in place in the implementation that does a get and then a put.
I can't force the underlying cache to lock on the key when I do the get, so another thread could potentially put something in before I replaced the value in the workaround case (in other words, it's best if the underlying method gets fixed in ehcache)
I have the following default configuration that I want to be applied to all caches created by CacheManager.createCache()
. Here is my ehcache.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<!-- see http://www.ehcache.org/ehcache.xml -->
<defaultCache
maxEntriesLocalHeap="200000"
eternal="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200">
<persistence strategy="localTempSwap"/>
</defaultCache>
</ehcache>
I try to create the cache as follows:
String providerName = "org.ehcache.jcache.JCacheCachingProvider";
CachingProvider cachingProvider = Caching.getCachingProvider(providerName);
CacheManager cacheManager = cachingProvider.getCacheManager();
CompleteConfiguration<ComposedKey, Object> config = new MutableConfiguration<ComposedKey, Object>()
.setTypes(ComposedKey.class, Object.class)
.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new AccessedExpiryPolicy(new Duration(TimeUnit.MINUTES, 30))))
.setReadThrough(false)
.setWriteThrough(false)
.addCacheEntryListenerConfiguration(
new MutableCacheEntryListenerConfiguration<ComposedKey, Object>(new CacheListenerManagerJSR107Factory(), null, true,
true));
;
Cache<ComposedKey, Object> cache = cacheManager.createCache("cache", config);
But it seems the default cache configuration is not used as when debugging the cache has the following attributes:
[ name = orACJ2rF-1 status = STATUS_ALIVE eternal = false overflowToDisk = false maxEntriesLocalHeap = 1000 maxEntriesLocalDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 0 timeToIdleSeconds = 0 persistence = none diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: org.ehcache.jcache.JCacheListenerAdapter ; orderedCacheEventListeners: maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]
Also, When I declare a named cache in ehcache.xml
and give the same name to CacheManager.createCache()
I get a javax.cache.CacheException at org.ehcache.jcache.JCacheManager.createCache(JCacheManager.java:106)
Hi, I think someone forgot to return the casted cacheManager.
So instead of
@Override
public <T> T unwrap(final Class<T> clazz) {
if(clazz.isAssignableFrom(getClass())) {
return clazz.cast(this);
}
if(clazz.isAssignableFrom(cacheManager.getClass())) {
clazz.cast(cacheManager);
}
throw new IllegalArgumentException();
}
it should be
@Override
public <T> T unwrap(final Class<T> clazz) {
if(clazz.isAssignableFrom(getClass())) {
return clazz.cast(this);
}
if(clazz.isAssignableFrom(cacheManager.getClass())) {
return clazz.cast(cacheManager);
}
throw new IllegalArgumentException();
}
Or am I missing something?
At least readmes are outdated.
But potentially more
Hi
The following source files are without license headers:
./ehcache-jcache/src/main/java/org/ehcache/jcache/JCacheManagementMXBean.java
./ehcache-jcache/src/main/java/org/ehcache/jcache/JCacheMXBean.java
./ehcache-jcache/src/main/java/org/ehcache/jcache/JCacheStatMXBean.java
./ehcache-jcache/src/main/java/org/ehcache/jcache/tck/TCKMBeanServerBuilder.java
./ehcache-jcache/src/test/java/org/ehcache/jcache/JCacheAndEhcacheAccessTest.java
./ehcache-jcache/src/test/java/org/ehcache/jcache/JCacheCachingProviderTest.java
./ehcache-jcache/src/test/java/org/ehcache/jcache/JCacheManagerTest.java
Please, confirm the licensing of code and/or content/s, and add license headers
https://fedoraproject.org/wiki/Packaging:LicensingGuidelines?rd=Packaging/LicensingGuidelines#License_Clarification
Thanks in advance
Regards
About:
net.sf.ehcache.jcache.JCacheListenerAdapter.implementsMethods
This function is called like this:
removedListener = implementsMethods(CacheEntryRemovedListener.class);
createdListener = implementsMethods(CacheEntryCreatedListener.class);
updatedListener = implementsMethods(CacheEntryUpdatedListener.class);
expiredListener = implementsMethods(CacheEntryExpiredListener.class);
Though implemented like this:
private boolean implementsMethods(Class cls) {
return cacheListener.getClass().isAssignableFrom(cls);
}
But should be implemented like this:
private boolean implementsMethods(Class cls) {
return cls.isAssignableFrom(cacheListener.getClass());
}
See: http://www.ralfebert.de/blog/java/isassignablefrom/
This stops any EventListeners from working at all.
In V load(K key)
method of org.ehcache.jcache.JCache
class ehcache.acquireWriteLockOnKey(key)
lock doesn't released when value exists.
Lock must be acquired if value not exists in cache.
V load(K key) {
V value;
final Element e = ehcache.get(key);
if(e != null) {
return (V)e.getObjectValue();
}
try {
ehcache.acquireWriteLockOnKey(key);
try {
value = cacheLoader.load(key);
} catch (Exception ex) {
throw new CacheLoaderException(ex);
}
if(value != null) {
putWithoutWriter(key, value);
}
} finally{
ehcache.releaseWriteLockOnKey(key);
}
return value;
}
We probably should either remove or upgrade the TCK from this project.
I may be in favor of the former... Probably better if we use the JSR's TCK directly (what I did for this 1.0.0-rc upgrade btw)
Shouldn't JCacheStatMXBean
clear the stats?
The two methods getCacheMissPercentage() and getCacheHitPercentage() throw an ArithmeticException (dividing by zero) if you want to print statistics after the cache just started (hit + miss count = 0).
Workarounds are:
@OverRide
public float getCacheMissPercentage() {
long sum = this.statistics.getCacheHitCount() + this.statistics.getCacheMissCount();
if (sum <= 0) {
return 0;
}
return (float) (this.statistics.getCacheMissCount() / ((double)sum)) * 100;
}
respectively
@OverRide
public float getCacheHitPercentage() {
long sum = this.statistics.getCacheHitCount() + this.statistics.getCacheMissCount();
if (sum <= 0) {
return 0;
}
return (float) ((this.statistics.getCacheHitCount() / ((double)sum)) * 100);
}
Cache element expiry does not seem to work properly when the JCache API is used with a cache that is configured through ehcache.xml.
ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<cache name="cache123"
maxEntriesLocalHeap="123"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="1"
timeToLiveSeconds="1"
memoryStoreEvictionPolicy="LRU">
</cache>
</ehcache>
My understanding is that the above config file creates an in-memory cache with 123 elements, and that elements time out after 1 second. I believe the following test case verifies my assumptions, note that the second test case uses the unwrapped ehcache instance from the JCache API:
EhCache test case:
package org.example;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.ehcache.jcache.JCache;
import org.junit.Assert;
import org.junit.Test;
import javax.cache.Caching;
public class EhCacheTest {
private final String cacheName = "cache123";
private void checkCache(Cache cache) throws InterruptedException {
Assert.assertNull("Cache should initially be empty", cache.get("test"));
cache.put(new Element("test", new Object()));
Assert.assertNotNull("Should not have timed out", cache.get("test"));
Thread.sleep(2000);
Assert.assertNull("Should have timed out", cache.get("test"));
}
@Test
public void testEhCacheDirect() throws InterruptedException {
CacheManager manager = CacheManager.newInstance();
Cache cache = manager.getCache(cacheName);
checkCache(cache);
}
@Test
public void testEhCacheFromJCache() throws InterruptedException {
JCache jcache = Caching.getCachingProvider().getCacheManager().getCache(cacheName).unwrap(JCache.class);
Cache cache = (Cache) jcache.unwrap(Cache.class);
checkCache(cache);
}
}
The above tests are both successful. When accessing the "same" cache through the JCache API however, the elements does not seem to expire. The test testJCacheXmlConfigured
below consistently fails on the third assert ("Should have timed out by now").
JCache test case:
package org.example;
import org.junit.Assert;
import org.junit.Test;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ModifiedExpiryPolicy;
import javax.cache.spi.CachingProvider;
import java.util.concurrent.TimeUnit;
public class JCacheTest {
CachingProvider provider = Caching.getCachingProvider();
CacheManager manager = provider.getCacheManager();
protected void checkCache(Cache cache) throws InterruptedException {
final String key = "test";
Assert.assertNull("Cache should initially be empty", cache.get(key));
cache.put(key, new Object());
Assert.assertNotNull("Should not have timed out yet", cache.get(key));
Thread.sleep(2000);
Assert.assertNull("Should have timed out by now", cache.get(key));
}
@Test
public void testJCacheManuallyConfigured() throws InterruptedException {
CachingProvider provider = Caching.getCachingProvider();
CacheManager manager = provider.getCacheManager();
Cache cache = manager.createCache("myManuallyConfiguredCache",
new MutableConfiguration()
.setStoreByValue(false)
.setExpiryPolicyFactory(
ModifiedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 1000))
));
checkCache(cache);
}
@Test
public void testJCacheXmlConfigured() throws InterruptedException {
final String cacheName = "cache123";
Cache cache = manager.getCache(cacheName);
checkCache(cache);
}
}
It looks like ehcache-jcache does not support ehcache 2.4/2.6.
Ehcache 2.4 on the other hand is the only ehcache version supported by hibernate 4.
https://hibernate.atlassian.net/browse/HHH-8732
and
hibernate/hibernate-orm#643
So if I see this correctly it's not possible to have an application which is using both hibernate and ehcache and also use the jcache interface for application specific caches?
Did I miss something?
I am trying to use a region named default
using ehcache-jcache
. When I tries to create it using the standard JSR-107 API, I get the following exception:
Caused by: net.sf.ehcache.ObjectExistsException: The Default Cache has already been configured
at net.sf.ehcache.config.Configuration.addCache(Configuration.java:967) ~[ehcache-2.8.3.jar:2.8.3]
at net.sf.ehcache.config.CacheConfiguration.registerCacheConfiguration(CacheConfiguration.java:1875) ~[ehcache-2.8.3.jar:2.8.3]
at net.sf.ehcache.config.CacheConfiguration.setupFor(CacheConfiguration.java:1703) ~[ehcache-2.8.3.jar:2.8.3]
at net.sf.ehcache.config.CacheConfiguration.setupFor(CacheConfiguration.java:1678) ~[ehcache-2.8.3.jar:2.8.3]
at net.sf.ehcache.CacheManager.initializeEhcache(CacheManager.java:1328) ~[ehcache-2.8.3.jar:2.8.3]
at net.sf.ehcache.CacheManager.addCacheNoCheck(CacheManager.java:1399) ~[ehcache-2.8.3.jar:2.8.3]
at net.sf.ehcache.CacheManager.addCacheIfAbsent(CacheManager.java:1916) ~[ehcache-2.8.3.jar:2.8.3]
at org.ehcache.jcache.JCacheManager.createCache(JCacheManager.java:108) ~[jcache-1.0.0.jar:na]
When I only try to access it (i.e. without creating it myself), I get:
java.lang.IllegalArgumentException: Cannot find cache named 'default' for CacheResultOperation[CacheMethodDetails[method=public java.lang.String demo.FooServiceImpl.defaultGet(long), [email protected](cacheKeyGenerator=interface javax.cache.annotation.CacheKeyGenerator, cacheName=default, cachedExceptions=[], skipGet=false, cacheResolverFactory=interface javax.cache.annotation.CacheResolverFactory, exceptionCacheName=, nonCachedExceptions=[]), cacheName='default']]
at org.springframework.cache.interceptor.AbstractCacheResolver.resolveCaches(AbstractCacheResolver.java:81)
at org.springframework.cache.jcache.interceptor.AbstractCacheInterceptor.resolveCache(AbstractCacheInterceptor.java:61)
at org.springframework.cache.jcache.interceptor.CacheResultInterceptor.invoke(CacheResultInterceptor.java:49)
at org.springframework.cache.jcache.interceptor.JCacheAspectSupport.execute(JCacheAspectSupport.java:131)
at org.springframework.cache.jcache.interceptor.JCacheAspectSupport.execute(JCacheAspectSupport.java:102)
at org.springframework.cache.jcache.interceptor.JCacheInterceptor.invoke(JCacheInterceptor.java:61)
Sample project available here
The spec says:
"The platform MBeanServer is obtained using ManagementFactory.getPlatformMBeanServer()"
but the current enableManagement implementation uses registerObject which is implemented as follows
private void registerObject(final JCacheMXBean cacheMXBean) throws NotCompliantMBeanException,
InstanceAlreadyExistsException, MBeanRegistrationException, MalformedObjectNameException {
final ObjectName objectName = new ObjectName(cacheMXBean.getObjectName());
if(mBeanServer.queryNames(objectName, null).isEmpty()) {
mBeanServer.registerMBean(cacheMXBean, objectName);
}
}
mBeanServer is a newly created MBeanServer and is not obtained using ManagementFactory.getPlatformMBeanServer().
in the branch 0.5-api-changes there is a version that currently compiles against the 0.5 spec but doesn't pass the TCK tests yet.
(most notably because the CacheEntryProcessor isn't implemented yet - it's just a stubbed method throwing an exception right now)
The CacheEntryProcessor might not be that hard to implement (I haven't spent any time trying to do it yet)
As far as I'm able to tell, if I configure the cache with an ehcache.xml and have set the cache to be eternal, this is getting ignored as the constructor of JCacheConfiguration always sets up an expiry policy.
Trying to build a very simple example according to Greg's blog I came across this one:
Cache<Integer, String> cache = cacheManager.getCache(cacheName);
cache == null
If I use the createCacheBuilder I actually get the cache instance ...
Had a problem with caches that seem to loose their expiry information.
Tracked down the problem to be caused by calling getCache on a non-existing cache.
It was used to check if the cache existed and if not, create it.
It looks like when JCacheManager.getCache() are not finding a cache in allCaches it
calls refreshallCaches() which will recreate them, but the expiry-configuration seems to be lost.
This test will show the error as the last assert will fail because the expiry-policy is lost.
@Test
public void testRefreshAllCachesError() {
final CachingProvider cachingProvider = Caching.getCachingProvider();
final CacheManager cacheManager = cachingProvider.getCacheManager();
String cacheNameExisting = "existingCache";
String cacheNameNonExisting = "nonExistingCache";
MutableConfiguration configuration = new MutableConfiguration();
configuration.setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 60)));
configuration.setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 60)));
cacheManager.createCache(cacheNameExisting, new JCacheConfiguration(configuration));
Cache<Object, Object> sampleCache = cacheManager.getCache(cacheNameExisting);
assertNotNull(sampleCache);
assertThat(sampleCache.getConfiguration(JCacheConfiguration.class).getExpiryPolicy().getExpiryForCreation().getDurationAmount(), is(60l));
// this will trigger refreshAllCaches which recreates caches
assertNull(cacheManager.getCache(cacheNameNonExisting));
// existing cache is OK but ...
assertThat(sampleCache.getConfiguration(JCacheConfiguration.class).getExpiryPolicy().getExpiryForCreation().getDurationAmount(), is(60l));
// ... if we fetch it again from cacheManager:
// this will fail as cache existingCache has been recreated and lost its expiry-policy
sampleCache = cacheManager.getCache(cacheNameExisting);
assertThat(sampleCache.getConfiguration(JCacheConfiguration.class).getExpiryPolicy().getExpiryForCreation().getDurationAmount(), is(60l));
}
Hi,
I am new to caching, please help me solve cachingprovider exceptions.
I want to test this sample code.
String cacheName = "sampleCache";
CacheManager cacheManager = Caching.getCacheManager();
javax.cache.Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cache = cacheManager.createCacheBuilder(cacheName).build();
}
cache.put("key","value for given key");
String fetchedcachevalue = cache.get("key");
System.out.println(fetchedcachevalue+" is the fetched cache value for given key");
in build path i path i gave cache-api-0.5.jar
When i run this, i got "No CachingProviders found in classpath." exception.
Then i gave "ehcache-jcache-1.5.0-0.5.jar" ,
then i got "Exception in thread "Main Thread" java.util.ServiceConfigurationError: javax.cache.spi.CachingProvider: Provider net.sf.ehcache.jcache.JCacheCachingProvider could not be instantiated: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory"
then i gave "ehcache-core-2.6.2.jar" ," slf4j-api-1.6.1.jar" , "slf4j-jdk14-1.6.1.jar"
and got exception saying "Exception in thread "Main Thread" java.lang.NoClassDefFoundError: javax/cache/implementation/AbstractCacheManagerFactory"
then i gave "cache-ri-impl-0.5.jar" and got "Exception in thread "Main Thread" java.lang.IllegalStateException: Multiple CachingProviders found in classpath. There should only be one. CachingProviders found were: net.sf.ehcache.jcache.JCacheCachingProvider, javax.cache.implementation.RICachingProvider"
now if i remove either "ehcache-jcache-1.5.0-0.5.jar" or "cache-ri-impl-0.5.ja" , i am getting the same exception when run ,saying "Exception in thread "Main Thread" java.lang.NoClassDefFoundError: javax/cache/implementation/AbstractCacheManagerFactory".
and if i remove both "ehcache-jcache-1.5.0-0.5.jar" and "cache-ri-impl-0.5.ja" , then i am getting exception say "Exception in thread "Main Thread" java.lang.IllegalStateException: No CachingProviders found in classpath."
Please help me run this sample code.
Thanks
I'm having the following exception when I read an entry that doesn't exist in the cache while I'm expecting a null
. Do I have to provide a factory for the cache loader when I create the cache? currently I'm not.
javax.cache.integration.CacheLoaderException: java.lang.NullPointerException
at org.ehcache.jcache.JCache.load(JCache.java:123)
at org.ehcache.jcache.JCache.get(JCache.java:105)
...
Here is my configuration:
CompleteConfiguration<ComposedKey, Object> config1 = new MutableConfiguration<ComposedKey, Object>()
// Configure the cache to be typesafe
.setTypes(ComposedKey.class, Object.class)
// Configure to expire entries 30 secs after creation in the cache
.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new AccessedExpiryPolicy(new Duration(TimeUnit.MINUTES, 30))))
// Configure read-through of the underlying store
.setReadThrough(true)
// Configure write-through to the underlying store
.setWriteThrough(true)
// Configure the javax.cache.integration.CacheLoader
// .setCacheLoaderFactory(FactoryBuilder.factoryOf(new UserCacheLoader(userDao)))
// Configure the javax.cache.integration.CacheWriter
// .setCacheWriterFactory(FactoryBuilder.factoryOf(new UserCacheWriter(userDao)))
// Configure the javax.cache.event.CacheEntryListener with no
// javax.cache.event.CacheEntryEventFilter, to include old value
// and to be executed synchronously
.addCacheEntryListenerConfiguration(
new MutableCacheEntryListenerConfiguration<ComposedKey, Object>(new CacheListenerManagerJSR107Factory(), null, true,
true));
It looks like when readTrough is set to true
then a cache loader should be provided.
i.e. jsr & tck to 1.0.0 and ehcache to latest 2.8(.3)
Hi,
the eventlisteners were not working at all, because of the wrong type being expected in the listener.
I've fixed the bug in this commit in my branch: https://github.com/subes/ehcache-jcache/commit/b9eb9f894145915c91f4817dd78ed682316c8dea
It would be nice if you could implement something similar in your branch, to make the listeners work.
Ryan has done an implementation.
Error Message
Expected: is <360> got: <1000>
Stacktrace
java.lang.AssertionError:
Expected: is <360>
got: <1000>
at org.junit.Assert.assertThat(Assert.java:778)
at org.junit.Assert.assertThat(Assert.java:736)
at org.ehcache.jcache.JCacheCachingProviderTest.testLoadsXMLFile(JCacheCachingProviderTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:78)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)
Its great that somebody picked this up and is updating it to comply with the latest version of the spec. Do you have plans to release this to a Maven repo soon (even in SNAPSHOT form)?
This works :
JCacheConfiguration jCacheConfiguration = new JCacheConfiguration(null, null, null, null);
cache = cacheManager.createCache(this.name, jCacheConfiguration);
while this gives me a NPE :
CacheConfiguration cacheConfiguration = new CacheConfiguration();
cacheConfiguration.setTimeToLiveSeconds(NO_EXPIRE);
cacheConfiguration.setTimeToIdleSeconds(NO_EXPIRE);
JCacheConfiguration jCacheConfiguration = new JCacheConfiguration(cacheConfiguration);
cache = cacheManager.createCache(this.name, jCacheConfiguration);
where NO_EXPIRE
is equal to 60 * 60 * 24 * 365 * 10
The only difference I see on code paths is that the second doesn't set an expire factory, while the first path does.
I use a cache configured with
copyOnRead="true"
copyOnWrite="true"
In the processor the code looks more or less like this:
Value value = entry.getValue();
value.modifySomehow();
entry.setValue(value);
after this, the cache remains unchanged.
Looking at the code it's easy to see why
in JCache, line 884
void apply(final JCache<K, V> jCache) {
if(deleted && !skipDelete) {
jCache.remove(key);
}
if(newValue != initialValue && newValue != null) {
jCache.put(key, newValue);
}
}
So in my case newValue == initialValue but it should still do a put as the value was modified. Maybe if it's using copyOnRead/copyOnWrite it should always put the value? Or is there something I missed/another way I can force an update (besides actually creating a new Value object which I'd rather not do).
getCache(cacheName, keyType, valueType) should work for pre-configured cache.
Make the 1.0.0 release happen!
Currently the StoreByValueTest#get_existing_MutateKey() and StoreByValueTest#getAndPut_Existing_NonSameKey_MutateKey tests in the TCK fail
As far as I understand, jsr-107's CacheManager
is supposed to be thread-safe, and it is only practical for it to be.
There is a possibility for the cache configuration created by JCacheManager.createCache()
to be configured incorrectly if JCacheManager.getCache()
is called at the same time with the same cache name. In particular, there is a realistic chance that the statistics and management beans are not created.
This works as follows:
createCache
is called.createCache
makes sure allCaches
does not include the cachecreateCache
adds the cache to the ehCache-backed cacheManager
getCache(String, Class, Class)
is called with the same argument.getCache
tries to find the same cache in allCaches
but does it does not existgetCache
looks in the ehCache-backed cacheManager
, and finds the cache as it's already added theregetCache
creates a new JCache
based on a JCacheConfiguration
with the default configuration and puts it into allCaches
createCache
creates a new JCache
with the correct configuration and tries to add it with allCaches.putIfAbsent
, but it already existscreateCache
returns the misconfigured cache that is already present in allCaches
, and does not call enableStatistics
or enableManagement
for it.The same problem occurs when using the second overload, getCache(String)
:
createCache
is called.createCache
makes sure allCaches
does not include the cachecreateCache
adds the cache to the ehCache-backed cacheManager
getCache(String)
is called with the same cache name as argument.getCache
looks in allCaches
, but does not find the cachegetCache
calls refreshAllCaches()
refreshAllCaches
iterates over all caches in the ehCache-backed cacheManager
, creates new JCache
instances for them and puts them into allCaches
new JCacheConfiguration()
does not properly set the managementEnabled
and statisticsEnabled
attributes when a ehCache CacheConfiguration
is provided as argumentcreateCache
again uses the already existing, but misconfigured cache and returns that, enableStatistics
and enableManagement
are not called.I see three possibilities to solve this problem:
synchronized
on all the methods touching or reading allCaches
. This may lead to performance loss, but is the simplest to implementReadWriteLock
so that concurrent e.g. getCache
or getCacheNames
can be called concurrently.allCaches
for those in this set. However, I don't think this will work because getCache
is expected to wait for a cache being added to be completely configured befure returning it. That's only possible with locking.I will create a pull request to fix this when we have agreed on a solution.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.