Bug: DefaultCache#entrySet() returns CacheObject<V> instead of <V> (+fix)

Note that in the current implementation, the entrySet will return a copy of the internal storage:

public Set entrySet() {
  // First, clear all entries that have been in cache longer than the
  // maximum defined age.
  deleteExpiredEntries();
  // TODO Make this work right   synchronized (this) {
    return new HashSet(map.entrySet());
  }
}

This internal storage stores not the raw types, but wrapped raw types. Unwrapping should occur before the EntrySet is returned:

public Set<Entry<K, V>> entrySet() {
  // First, clear all entries that have been in cache longer than the
  // maximum defined age.
  deleteExpiredEntries();
  // TODO Make this work right   synchronized (this) {
    final Map<K,V> result = new HashMap<K,V>();
    for (final Entry<K, DefaultCache.CacheObject<V>> entry : map.entrySet()) {
      result.put(entry.getKey(), entry.getValue().object);
    }
    return result.entrySet();
  }
}

Note that this still does not return an EntrySet that backs the collection, but at least the correct objects are now returned.

Hey Guus,

Thanks for pointing this out. I have been checking the usages of this method and it’s very interesting that it never threw a casting exception. Basically the reason was that when running in a cluster we use other type of caches and when not running in a cluster we do not reach that code. In other words, it was a matter of time to hit this error so thanks for hunting it.

The fix was included for Openfire 3.4.2 to be released this week.

Regards,

– Gato

We only found it because one of my co-workers started using it in a Plugin Thanks for patching it!