Bug in OSCache Serialization

[email protected]
Newsgroups gmane.comp.java.open-symphony.os-cache
Message-ID <OF61C8AAC6.52680372-ON85256E8D.003F0771-80256E8D.0040F369@checkfree.com>
Hi

I have found a bug in the OSCache deserialization code. I have seen 
similar problem in JIRA, but I haven't seen the proper solution yet. 

The main issue is with the AbstractConcurrentReadCache class. In the 
readObject() method, it executes the following code to repopulate the 
cache:

for (int i = 0; i < size; i++) {
            Object key = s.readObject();
            Object value = s.readObject();
            put(key, value);
        }

The problem is with the call to put(). This delegates to the algorithm 
subclass (e.g. LRUCache), which attempts to add an entry to the actual 
Collection containing the cache entries. However, the underlying 
Collection does not seem to have been read from the stream at this point, 
and thus is not initalized. So we always get a NPE at this point after 
deserialization. 

I think it's pretty reasonable to want to be able to (de)serialize a 
GeneralCacheAdministrator, say in a HttpSession, so I think this is a bug. 
An interim solution is to copy the Collection definition into the 
superclass and change its access modifier, so the line:

protected Collection list;

is moved up into AbstractConcurrentReadCache. This may break the design , 
however, it does ensure that the Collection is initialized by the time 
AbstractConcurrentCache::defaultReadObject() returns.

There is also another bug -  the locking Object barrierLock, is marked as 
transient (and indeed, being an instance of java.lang.Object, 
non-Serializable by default), so  post-deserialization, any attempts to 
use this as a lock will throw a NPE. The solution is to remove the 'final' 
attribute from barrierLock and re-initialize it inside readObject():

private synchronized void readObject(java.io.ObjectInputStream s) throws 
IOException, ClassNotFoundException {
 
 
    // Read in the threshold, loadfactor, and any hidden stuff
    s.defaultReadObject();
 
   // Re-initialize the barrierLock
   barrierLock = new Object();

This should solve both issues, and everything should now serialize and 
deserialize properly.

Cheers,
Rory



Rory Winston
Systems Consultant
EMEA Region 

http://www.checkfreeisolutions.com 
226 Berwick Ave.
Slough, Berkshire SL1 4QT
United Kingdom
Direct: +44 (0) 1753 285984
Mobile: +44 (0) 7775 664854
Fax: +44 (0) 1753 567-897
[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.