[ 
https://issues.apache.org/jira/browse/JCR-2382?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12891554#action_12891554
 ] 

Benjamin Brown commented on JCR-2382:
-------------------------------------

The same fault has been noticed when operating Jackrabbit 1.6.2 in a cluster 
(not sure if the cluster has any bearing on the issue) and an update to 
existing content is being performed. About 70% of the time it is successful 
otherwise it throws an NPE. The patch provided by the OP does fix the issue.

> 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.

Reply via email to