The returned map from the node seems to be an instance of java.util.Collections$UnmodifiableMap. The javadoc for the UnmodifiableMap specifies:
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
Returns an unmodifiable view of the specified map. This method allows modules to provide users with "read-only" access to internal maps. Query operations on the returned map "read through" to the specified map, and attempts to modify the returned map, whether direct or via its collection views, result in an UnsupportedOperationException.
The returned map will be serializable if the specified map is serializable.
m - the map for which an unmodifiable view is to be returned.
an unmodifiable view of the specified map.
I would say it is plausible that the unmodifiedMap provides an immutable view but is still backed by a map which will reflect changes to the underlying data thus creating a map which is not safe to iterate in concurrent situations.
Thanks for spotting this, this is quite a nasty problem. You're correct in that it ought to be defensively copied while we still have locks on the node, to prevent this issue.
I'm going to create a JIRA and unit test for this, but for the time being if you want a workaround you could try this:
1. Start a tx
3. Make your own defensive copy. This won't be any more expensive than JBoss Cache doing this internally for you.
4. Commit your tx.
That would guarantee that you don't end up with a ConcurrentModificationException.
FYI - JBCACHE-1337
Cheers. The JIRA issue is currently due for 2.2.0, is this correct or do you think it might be included in 2.1.1? If the fix is likely to be included in 2.1.1 then we wont bother with implementing a workaround but rather wait for 2.1.1 =)
Sadly, 2.1.1 is in QA right now and very close to being released. If there was no workaround, I would have "stopped the presses" for this, but since there is a workaround I'd prefer not to do that.