Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
jcs-2.0-beta-1
-
None
Description
One of our users got the following exception:
java.lang.NullPointerException
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache.addToRecycleBin(IndexedDiskCache.java:1181)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache$LRUMapSizeLimited.processRemovedLRU(IndexedDiskCache.java:1785)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache$LRUMapSizeLimited.processRemovedLRU(IndexedDiskCache.java:1684)
at org.apache.commons.jcs.utils.struct.AbstractLRUMap.put(AbstractLRUMap.java:344)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache$LRUMapSizeLimited.put(IndexedDiskCache.java:1732)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache$LRUMapSizeLimited.put(IndexedDiskCache.java:1684)
at org.apache.commons.jcs.utils.struct.AbstractLRUMap.putAll(AbstractLRUMap.java:187)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache.loadKeys(IndexedDiskCache.java:343)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache.initializeStoreFromPersistedData(IndexedDiskCache.java:286)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache.initializeKeysAndData(IndexedDiskCache.java:250)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCache.<init>(IndexedDiskCache.java:182)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory.createCache(IndexedDiskCacheFactory.java:60)
at org.apache.commons.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory.createCache(IndexedDiskCacheFactory.java:33)
My guess is, that during cache initialization doOptimizeRealTime() spawned a new thread calling optimizeFile().
optimizeFile() does all actions governed by storageLock.writeLock(), but there are no guarantees, in which order addToRecycleBin() will see changes done by optimizeFile.
I see two solutions to this problem:
1. Protect addToRecycleBin using storageLock.readLock() to ensure the same order of reads and writes with optimizeFile
2. Use volatile keyword on doRecycle / recycle objects and use Java Memory Model guarantees to order writes and reads in this two methods
My feeling is that 1st solution is more coherent with current approach within JCS.