jackrabbit-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Cele Liu (JIRA)" <j...@apache.org>
Subject [jira] Created: (JCR-2382) NPE when calling node.getBaseVersion() within the transaction.
Date Wed, 04 Nov 2009 03:51:34 GMT
NPE when calling node.getBaseVersion() within the transaction.
--------------------------------------------------------------

                 Key: JCR-2382
                 URL: https://issues.apache.org/jira/browse/JCR-2382
             Project: Jackrabbit Content Repository
          Issue Type: Bug
          Components: jackrabbit-core
    Affects Versions: 1.6.0
         Environment: winxp
            Reporter: Cele Liu


We try to get the base version from a versionable node in the transaction, but if we didn't
check in the node, the NPE will throw out. We used the jr-jcr to support XA transaction.
the code likes:
        UserTransaction ut = null;
        InitialContext tx = new InitialContext();
        ut = (UserTransaction) tx.lookup("UserTransaction");
        ut.begin();
        try {
            Session session = getJcrSession();
            Node root = session.getRootNode();
            Node child = root.addNode("testchild");
            root.save();
            child.addMixin(JcrConstants.MIX_VERSIONABLE);
            child.save();
            session.save();
            //child.checkin();
            javax.jcr.version.Version v = child.getBaseVersion();
            session.logout();
            ut.commit();
        }catch(Exception e){
            ut.rollback();
            e.printStackTrace(System.err);
            fail("failed with " + e.getMessage());
        }
The exception stack:
java.lang.NullPointerException
      at org.apache.jackrabbit.core.NodeImpl.getBaseVersion(NodeImpl.java:3659)
      at com.vitria.modeling.repository.sapi.JcrTransactionTest.testBaseVersionableSample(JcrTransac
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

If we did not run the code in XA transaction or check-in the code before calling the child.getBaseVersion(),
the NPE will be gone.
JR1.5.0 doesn't have this issue.

I compare the code between JR1.5.0 and JR 1.6.0. and get some clue.

Please check the code snippet for JR 1.6.0. Looks like in JR 1.6.0, it always look up the
node from the version manager.
The NPE happens if the versioned node doesn't exist, v is null and then JR try to get node
by the v.getId().

public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException
{
        // check state of this instance
        sanityCheck();
        boolean isFull = checkVersionable();
        InternalVersion v;
        if (isFull) {
            NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_BASEVERSION).getString());
            v = session.getVersionManager().getVersion(id);
        } else {
            // note, that the method currently only works for linear version
            // graphs (i.e. simple versioning)
            v = session.getVersionManager().getHeadVersionOfNode(((NodeId) id));
        }
        return (Version) session.getNodeById(v.getId());
}

And there is the code snippet for JR 1.5.0, JR doesn't depends on the version manager, it
always get the version from the property.

public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException
{
        // check state of this instance
        sanityCheck();
        checkVersionable();
       // transactions workaround.
        NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_BASEVERSION).getString());
        session.getVersionManager().getVersion(id);
        return (Version) getProperty(NameConstants.JCR_BASEVERSION).getNode();
}

Notice: For JR 1.5.0 and JR 1.6.0, if you didn't check in the node in XA transaction, the
API session.getVersionManager().getVersion(id); both will return null.
The difference is 1.6.0 will use the return to perform the look-up, and 1.5.0 doesn't. 

After I patch the code to below, the getBaseVersion() cases got passed:
public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException
{
        // check state of this instance
        sanityCheck();
        boolean isFull = checkVersionable();
        InternalVersion v;
        if (isFull) {
            NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_BASEVERSION).getString());
            v = session.getVersionManager().getVersion(id);
        } else {
            // note, that the method currently only works for linear version
            // graphs (i.e. simple versioning)
            v = session.getVersionManager().getHeadVersionOfNode(((NodeId) id));
        }
        if (v == null){
            return (Version) getProperty(NameConstants.JCR_BASEVERSION).getNode();
        }else{
            return (Version) session.getNodeById(v.getId());    
        }
}




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


Mime
View raw message