jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dan Diephouse (JIRA)" <j...@apache.org>
Subject [jira] Created: (JCR-2579) InvalidItemStateException when attempting concurrent, non conflicting writes
Date Mon, 22 Mar 2010 15:05:28 GMT
InvalidItemStateException when attempting concurrent, non conflicting writes

                 Key: JCR-2579
                 URL: https://issues.apache.org/jira/browse/JCR-2579
             Project: Jackrabbit Content Repository
          Issue Type: Bug
          Components: jackrabbit-core
    Affects Versions: 1.6.1
            Reporter: Dan Diephouse

I'm having some problems doing concurrent addition of nodes to a parent node in Jackrabbit.
 I've attached a simple test which starts up a bunch of threads which add nodes to a parent
node concurrently. If I add in locks I can get this to work, however according to the mailing
list this should work without locks. However, the test always fails with this:

javax.jcr.InvalidItemStateException: Item cannot be saved because it has been modified externally:
node /testParent
	at org.apache.jackrabbit.core.ItemImpl.getTransientStates(ItemImpl.java:281)
	at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:939)
	at org.mule.galaxy.impl.JackrabbitConcurrentWriteTest$1.run(JackrabbitConcurrentWriteTest.java:71)

I'm using Jackrabbit 1.6.1. Here is my (verbose) node type:

  <nodeType name="galaxy:noSiblings" 
    <propertyDefinition name="*" requiredType="undefined" onParentVersion="COPY" />
    <propertyDefinition name="*" requiredType="undefined" onParentVersion="COPY" multiple="true"/>
    <childNodeDefinition name="*" defaultPrimaryType="nt:unstructured" onParentVersion="COPY"
sameNameSiblings="false" />

And my test:    

package org.mule.galaxy.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;

import junit.framework.TestCase;

import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.TransientRepository;
import org.apache.jackrabbit.core.config.RepositoryConfig;

public class JackrabbitConcurrentWriteTest extends TestCase {
    private Repository repository;
    private Session session;
    private String parentUUID;
    private boolean continueLoop = true;
    public void setUp() throws Exception {
        FileUtils.deleteDirectory(new File("repository"));
        File repoDir = new File("repository");
        RepositoryConfig config = RepositoryConfig.create(new File("src/test/resources/META-INF/jackrabbit-repo-test.xml"),
        repository = RepositoryImpl.create(config);
        session = createSession();
        parentUUID = session.getRootNode().addNode("testParent", "galaxy:noSiblings").getUUID();

    private Session createSession() throws LoginException, RepositoryException {
        return repository.login(new SimpleCredentials("username", "password".toCharArray()));
    public void testConcurrency() throws Exception {
        final List<Exception> exceptions = new ArrayList<Exception>();
        int threadCount = 20;
        final CountDownLatch latch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            Thread thread = new Thread() {

                public void run() {
                    try {
                        while (continueLoop) {
                            Session session = createSession();
                            try {
                                Node node = session.getNodeByUUID(parentUUID);
                            } finally {
                    } catch (RepositoryException e) {
                        continueLoop = false;
        latch.await(10, TimeUnit.SECONDS);
        continueLoop = false;
        for (Exception e : exceptions) {
        assertEquals(0, exceptions.size());
    public void createCustomNodeTypes(Session session) throws RepositoryException, IOException
        // Get the JackrabbitNodeTypeManager from the Workspace.
        // Note that it must be cast from the generic JCR NodeTypeManager to
        // the Jackrabbit-specific implementation.
        // (see: http://jackrabbit.apache.org/node-types.html)
        JackrabbitNodeTypeManager manager = (JackrabbitNodeTypeManager) session.getWorkspace().getNodeTypeManager();

        // Register the custom node types defined in the CND file
        InputStream is = Thread.currentThread().getContextClassLoader()
        manager.registerNodeTypes(is, JackrabbitNodeTypeManager.TEXT_XML);

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message