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