Jackrabbit Content Repository
  1. Jackrabbit Content Repository
  2. JCR-3031

HierarchyManager become unsynchronized among processes after a session.move operation

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.2.5
    • Fix Version/s: None
    • Labels:
      None
    • Environment:
      Two machines M1, M2

      M1: OS X 10.6.6
      M2: WIN7 (as a VirtualBox machine)

      On both machines
      JRE 1.6

      Description

      Setup
      --------

      Two machines (M1, M2) ; M1 is running a process P1 and M2 is running the process P2
      P1 and P2 create one single repository instance (through Spi2davexRepositoryServiceFactory) and reuse it to open/close multiple sessions.

      Use case
      ------------

      In P1
      1. Create the following content
      /test
      /test/sub
      /test/file.txt
      2. create a new session
      3. Use (session.move()) in order to move the node /test/file.txt to /test/sub/file.txt
      4. save the changes (session.save())
      5. Close the session

      In P2
      1. Create a new session
      2. Get the moved node (Node n = session.getNode(/test/sub/file.txt)) -> works fine
      3. Get a property on the node (n.getProperty("jcr:content/jcr:lastModified")) -> throws a PathNotFoundException, eventhough the property exists in the repository (can be checked with an third process creating a new repository instance)
      4. Close the session

      Notes:

      • No Parallelism, P2 is run right after P1's step 5.
      • The PathNotFoundException is always thrown in P2.
      • On P2, Refreshing the session after the step 2. does not help.
      • The cache behavior is the default one, not CacheBehaviour.OBSERVATION

      Observations
      ------------

      In P2, the PathNotFound Exception is thrown in
      HierarchyManagerImpl.getPropertyEntry(Path qPath)
      getDeepPropertyEntry(qPath)
      // no valid ancestor node entry
      // -> if cnes are complete -> assume that it doesn't exist.
      // refresh will bring up new entries added in the mean time
      // on the persistent layer.
      if (entry.childNodeEntries.isComplete())

      { throw new PathNotFoundException(factory.saveGetJCRPath(path)); // HERE THROWS AN EXCEPTION (SEE DETAIL BELOW) }

      The try.childNodeEntries.isComplete() returns true when it should not. More in detail, the isComplete method gives:
      public boolean isComplete()

      { // HERE: complete = true, parent.status = EXISTING return (parent.getStatus() != Status.INVALIDATED && complete) || parent.getStatus() == Status.NEW || Status.isTerminal(parent.getStatus()); }

      }

      The parent.getStatus == EXISTING and I guess it should be invalidated due to the move operation.
      Anyway, it seems that the HierarchyManager get messed up

      Workaround
      ----------

      In P2, (step 1.) Get the session from a new Repository instance instead of reusing it.

      Note


      I'll add a test case to demo it later.

        Activity

        Hide
        Michael Dürig added a comment -

        There is a comment on RepositoryServiceImpl [1]: // TODO: TO-BE-FIXED. caches don't get adjusted upon removal/move of items

        Could this be causing the problem?

        [1] http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?view=markup

        Show
        Michael Dürig added a comment - There is a comment on RepositoryServiceImpl [1] : // TODO: TO-BE-FIXED. caches don't get adjusted upon removal/move of items Could this be causing the problem? [1]   http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?view=markup
        Hide
        Timothee Maret added a comment -

        I haven't tried with items removal, though it seems that this comment matches my use case for move operation.

        Show
        Timothee Maret added a comment - I haven't tried with items removal, though it seems that this comment matches my use case for move operation.
        Hide
        Timothee Maret added a comment -

        Hi Michael, I had a closer look at this issue and while writing a unit test for demonstrating this issue, I noticed that the davex RepositoryServiceImpl is actually overriding the move operation, thus, it shouldn't be related to the comment you mentionned above.

        I also wrote the test JCR-3031-TEST that basically reproduce the scenario I described in the bug description, except that the two processes are simulated as threads and ... that the test actually pass.

        I am really thinking that this issue is related to a multi-process environment, any idea how I could write a more complete test ?

        Show
        Timothee Maret added a comment - Hi Michael, I had a closer look at this issue and while writing a unit test for demonstrating this issue, I noticed that the davex RepositoryServiceImpl is actually overriding the move operation, thus, it shouldn't be related to the comment you mentionned above. I also wrote the test JCR-3031 -TEST that basically reproduce the scenario I described in the bug description, except that the two processes are simulated as threads and ... that the test actually pass. I am really thinking that this issue is related to a multi-process environment, any idea how I could write a more complete test ?

          People

          • Assignee:
            Unassigned
            Reporter:
            Timothee Maret
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:

              Development