5 Replies Latest reply on May 1, 2008 8:09 AM by manik

    Getting data from a node

    fredrikj

      We have seen ConcurrentModificationExceptions in our system when handling data maps returned from a node. In the JBC javadoc it is specified that the method Node.getData() should return an immutable map.

      Returns:
      a Map containing the data in this Node. If there is no data, an empty Map is returned. The Map returned is always immutable.


      Is this still true for 2.1.0.GA? Since there was no other way I could possibly see the exception occur in our system I whipped together a quick test to see if I could rely on the returned map not to change. What I found was that you cannot safely iterate the returned data map if other threads are changing the cache, which seems to imply that the returned map is not immutable.

      You can find the simple test here: http://www.cubeia.com/misc/nodedata/

      It is not possible to take a defensive copy of the map either since we then might end up with a ConcurrentModificationExceptions in the initialization of the new map (this was actually the case of the original error).

        • 1. Re: Getting data from a node
          fredrikj

          The returned map from the node seems to be an instance of java.util.Collections$UnmodifiableMap. The javadoc for the UnmodifiableMap specifies:

          unmodifiableMap

          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.

          Parameters:
          m - the map for which an unmodifiable view is to be returned.
          Returns:
          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.


          • 2. Re: Getting data from a node
            manik

            Hi

            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
            2. Node.getData()
            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.

            • 3. Re: Getting data from a node
              manik

              FYI - JBCACHE-1337

              • 4. Re: Getting data from a node
                fredrikj

                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 =)

                • 5. Re: Getting data from a node
                  manik

                  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.