You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2011/09/23 16:57:52 UTC

svn commit: r1174822 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java test/java/org/apache/jackrabbit/core/NPEandCMETest.java test/java/org/apache/jackrabbit/core/TestAll.java

Author: stefan
Date: Fri Sep 23 14:57:52 2011
New Revision: 1174822

URL: http://svn.apache.org/viewvc?rev=1174822&view=rev
Log:
JCR-3063 NullPointerException in ItemManager

Added:
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/NPEandCMETest.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=1174822&r1=1174821&r2=1174822&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Fri Sep 23 14:57:52 2011
@@ -771,14 +771,13 @@ public class SharedItemStateManager
 
             ISMLocking.ReadLock readLock = null;
             try {
+                // Let the shared item listeners know about the change
+                shared.persisted();
+
                 // downgrade to read lock
                 readLock = writeLock.downgrade();
                 writeLock = null;
 
-                // Let the shared item listeners know about the change
-                // JCR-2171: This must happen after downgrading the lock!
-                shared.persisted();
-
                 /* notify virtual providers about node references */
                 for (int i = 0; i < virtualNodeReferences.length; i++) {
                     ChangeLog virtualRefs = virtualNodeReferences[i];

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/NPEandCMETest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/NPEandCMETest.java?rev=1174822&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/NPEandCMETest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/NPEandCMETest.java Fri Sep 23 14:57:52 2011
@@ -0,0 +1,131 @@
+package org.apache.jackrabbit.core;
+
+import java.util.ConcurrentModificationException;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+public class NPEandCMETest extends AbstractJCRTest {
+
+    private final static int NUM_THREADS = 10;
+    private final static boolean SHOW_STACKTRACE = true;
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        Session session = getHelper().getSuperuserSession();
+        session.getRootNode().addNode("test");
+        session.save();
+    }
+    
+    protected void tearDown() throws Exception {
+        try {
+            Session session = getHelper().getSuperuserSession();
+            if (session.getRootNode().hasNode("test")) {
+                session.getRootNode().getNode("test").remove();
+                session.save();
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+    
+    public void testDo() throws Exception {
+        Thread[] threads = new Thread[NUM_THREADS];
+        TestTask[] tasks = new TestTask[NUM_THREADS];
+        for (int i = 0; i < NUM_THREADS; i++) {
+            Session session = getHelper().getSuperuserSession();
+            tasks[i] = new TestTask(i, session);
+        }
+        for (int i = 0; i < NUM_THREADS; i++) {
+            threads[i] = new Thread(tasks[i]);
+            threads[i].start();
+        }
+        for (int i = 0; i < NUM_THREADS; i++) {
+            threads[i].join();
+        }
+        int npes = 0, cmes = 0;
+        for(int i = 0; i < NUM_THREADS; i++) {
+            npes += tasks[i].npes;
+            cmes += tasks[i].cmes;
+        }
+        System.err.println("Total NPEs: " + npes);
+        System.err.println("Total CMEs: " + cmes);
+    }
+    
+    private static class TestTask implements Runnable {
+
+        private final Session session;
+        private final int id;
+        private final Node test;
+        
+        private int npes = 0;
+        private int cmes = 0;
+        
+        private TestTask(int id, Session session) throws RepositoryException {
+            this.id = id;
+            this.session = session;
+            test = this.session.getRootNode().getNode("test");
+        }
+        
+        public void run() {
+            try {
+                for (int i = 0; i < 500; i++) {
+                    NodeIterator nodes = test.getNodes();
+                    if (nodes.getSize() > 100) {
+                        long count = nodes.getSize() - 100;
+                        while (nodes.hasNext() && count-- > 0) {
+                            Node node = nodes.nextNode();
+                            if (node != null) {
+                                try {
+                                    node.remove();
+                                }
+                                catch (ItemNotFoundException e) {
+                                    // item was already removed
+                                }
+                                catch (InvalidItemStateException e) {
+                                    // ignorable
+                                }
+                            }
+                        }
+                        session.save();
+                    }
+                    test.addNode("test-" + id + "-" + i);
+                    session.save();
+                }
+                
+            }
+            catch (InvalidItemStateException e) {
+                // ignorable
+            }
+            catch (RepositoryException e) {
+                if (e.getCause() == null || !(e.getCause() instanceof NoSuchItemStateException)) {
+                    System.err.println("thread" + id + ":" + e);
+                    e.printStackTrace();
+                }
+                // else ignorable
+            }
+            catch (NullPointerException e) {
+                System.err.println("====> " + e);
+                if (SHOW_STACKTRACE) {
+                    e.printStackTrace();
+                }
+                npes++;
+            }
+            catch (ConcurrentModificationException e) {
+                System.err.println("====> " + e);
+                if (SHOW_STACKTRACE) {
+                    e.printStackTrace();
+                }
+                cmes++;
+            }
+        }
+        
+    }
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java?rev=1174822&r1=1174821&r2=1174822&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java Fri Sep 23 14:57:52 2011
@@ -80,6 +80,8 @@ public class TestAll extends TestCase {
 
         suite.addTestSuite(OverlappingNodeAddTest.class);
 
+        suite.addTestSuite(NPEandCMETest.class);
+
         return suite;
     }
 }