Uploaded image for project: 'Jackrabbit Content Repository'
  1. Jackrabbit Content Repository
  2. JCR-2494

Problem with ItemManager shareable node caches, eviction not propagated from one session to another

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Patch Available
    • Major
    • Resolution: Unresolved
    • 2.0
    • None
    • jackrabbit-core

    Description

      Hi,

      When deleting one share of a shareable node from a list with one session, the shareableNodesCache of the other session is not updated on save and the entry is not removed. There's no problem when the item is completely deleted - in that case, the ItemStateListener propagates the event to other sessions to evict the entries from the cach.

      This leads to some issues if the item is later retrieved with ItemManager.retrieveItem(id) - this one returns the first entry of the shareableNodesCache, which may be the one that has been deleted. The NodeData here has a primaryParentId - but the node behind this id does not have the shareable node as a child anymore. Subsequent calls to getName() or getPath() on this node throws exception ( failed to build path of xx: yy has no child entry for xx , from NodeImpl:3092)

      It's quite difficult to reproduce, and does not crashes everytime (as we're getting one item from the shareableNodesCache map), but we have some scenarios where this happens quite frequently - here's some code to reproduce the problem :

      // Create structure
      Node n1 = node.addNode("n1", "nt:unstructured");
      Node n2 = node.addNode("n2", "nt:unstructured");
      Node n3 = node.addNode("n3", "nt:unstructured");
      Node n4 = node.addNode("n4", "nt:unstructured");
      Node s1 = n1.addNode("s1", "nt:unstructured");

      s1.addMixin("mix:shareable");
      String id = s1.getIdentifier();
      session.save();
      session.getWorkspace().clone("default", s1.getPath(), n2.getPath() + "/s2", false);
      session.getWorkspace().clone("default", s1.getPath(), n3.getPath() + "/s3", false);
      session.getWorkspace().clone("default", s1.getPath(), n4.getPath() + "/s4", false);

      // Load caches
      session.getNode(node.getPath()+"/n1/s1").getPath();
      session.getNode(node.getPath()+"/n2/s2").getPath();
      session.getNode(node.getPath()+"/n3/s3").getPath();
      session.getNode(node.getPath()+"/n4/s4").getPath();

      // Remove shares from other session
      session2.getNode(node.getPath()+"/n1/s1").remove();
      session2.getNode(node.getPath()+"/n2/s2").remove();
      session2.getNode(node.getPath()+"/n4/s4").remove();
      session2.save();

      assertNotNull(session2.getNodeByIdentifier(id).getPath());
      assertNotNull(session.getNodeByIdentifier(id).getPath());

      I fixed the issue by adding a call to evictItems() in stateModified (actually, almost uncommenting the code that was already there). You'll find the patch attached.

      Regards

      Attachments

        Activity

          People

            Unassigned Unassigned
            draier Thomas Draier
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated: