• Bug
  • Status: New
  • 2 Major
  • Resolution:
  • ehcache-core
  • drb
  • Reporter: jeferson
  • February 09, 2015
  • 2
  • Watchers: 4
  • May 07, 2015

Description

Hello,

While trying to put a non serializable key to the Cache.put method, in ehcache-core 2.6.10, we get the following exception: net.sf.ehcache.CacheException: The key java.lang.Object@45d6a56e is not Serializable. Consider using Element.getObjectKey() at net.sf.ehcache.Element.getKey(Element.java:256) at net.sf.ehcache.store.MemoryStore.evict(MemoryStore.java:853) at net.sf.ehcache.store.NotifyingMemoryStore.evict(NotifyingMemoryStore.java:60) at net.sf.ehcache.store.MemoryStore.removeElementChosenByEvictionPolicy(MemoryStore.java:596) at net.sf.ehcache.store.MemoryStore.checkCapacity(MemoryStore.java:562) at net.sf.ehcache.store.MemoryStore.put(MemoryStore.java:262) at net.sf.ehcache.store.FrontEndCacheTier.put(FrontEndCacheTier.java:267) at net.sf.ehcache.Cache.putInternal(Cache.java:1455) at net.sf.ehcache.Cache.put(Cache.java:1383) at net.sf.ehcache.Cache.put(Cache.java:1348)

In version 2.6.9 it was working fine. Apparently this started happening after a change in the “NotifyingMemoryStore.evict” method in version 2.6.10.

We’ve created this unit test so you can reproduce the scenario: @Test public void testCacheWithNonSerializableKey() { Cache cache = new Cache(“test”, 100, false, true, 9000, 9000, false, 900); cache.setCacheManager(new CacheManager()); cache.initialise(); cache.getCacheConfiguration().setMaxEntriesLocalHeap(1L); cache.setMemoryStoreEvictionPolicy(new LruPolicy());

    for (int i = 0; i < 2; i++) {
        Element element = new Element(new Object(), "result");
        cache.put(element);
    }
}

Comments

Manuel Siggen 2015-05-07

I confirm the problem : evicting non-serializable elements from a memory store raises _XXX is not Serializable_ exceptions.

The bug seems to be in the following method :

    /**
     * Evicts the element from the store
     * @param element the element to be evicted
     * @return true if succeeded, false otherwise
     */
    protected boolean evict(final Element element) {
        final ReentrantReadWriteLock.WriteLock lock = map.lockFor(element.getObjectKey()).writeLock();
        if (lock.tryLock()) {
            final Element remove;
            try {
                remove = remove(element.getObjectKey());
            } finally {
                lock.unlock();
            }
            RegisteredEventListeners cacheEventNotificationService = cache.getCacheEventNotificationService();
            final FrontEndCacheTier frontEndCacheTier = cacheEventNotificationService.getFrontEndCacheTier();
            if (remove != null && frontEndCacheTier != null && frontEndCacheTier.notifyEvictionFromCache(remove.getKey())) {
                cacheEventNotificationService.notifyElementEvicted(remove, false);
            }
            return remove != null;
        }
        return false;
    }

=> the line _frontEndCacheTier.notifyEvictionFromCache(remove.getKey()))_ calls the _Element.getKey_ method (which is deprecated) and in turn raises an exception if the key is not serializable.