/** * Test case for * JCR-2908. */ public void testAddNodeInMultipleThreads() throws Exception { Session session = getHelper().getSuperuserSession(); // make sure that 'testNode' does not exist at the beginning // of the test while (session.nodeExists("/testNode")) { session.getNode("/testNode").remove(); session.save(); } // create 'testNode' that has two child Node node = session.getRootNode().addNode("testNode"); Node child1 = node.addNode("child1"); String child1Path = child1.getPath(); Node child2 = node.addNode("child2"); String child2Path = child2.getPath(); session.save(); session.logout(); //create versionable nodes under child1 and child2 //repeat several times for(int i=0; i<5; ++i){ CountDownLatch startSignal = new CountDownLatch(1); CountDownLatch endSignal = new CountDownLatch(2); AddNodeThread t1 = new AddNodeThread(child1Path, 20, startSignal, endSignal); t1.start(); AddNodeThread t2 = new AddNodeThread(child2Path, 20, startSignal, endSignal); t2.start(); startSignal.countDown(); endSignal.await(); assertTrue(t1.isSuccess()); assertTrue(t2.isSuccess()); } } class AddNodeThread extends Thread { private String parentPath; private int childCount=0; private boolean success = false; private CountDownLatch startSignal; private CountDownLatch endSignal; AddNodeThread(String parentPath, int childCount, CountDownLatch startSignal, CountDownLatch endSignal) { this.parentPath = parentPath; this.childCount = childCount; this.startSignal = startSignal; this.endSignal = endSignal; } public void run() { Session session = null; try { startSignal.await(); session = getHelper().getSuperuserSession(); UserTransaction utx = new UserTransactionImpl(session); utx.begin(); Node parent = session.getNode(parentPath); for(int i=0; i