Tobias Bocanegra wrote:
you can't use the xaresource directly

Why? I'm using an API that's legitimate and public.

you need to create a user transaction.

I'm the sole user of Jackrabbit and the transactions here. Behind the scene, a user transaction does exactly what I do: xaresource.start() with the proper arguments, do some work then end() it and commit() it. Jackrabbit's test/java/org/apache/jackrabbit/core/UserTransactionImpl.java is pretty simple.

and you can use the transaction only once.

I've updated my code to use different xid instances for each transaction, and it still crashes. Updated jython code attached.

Thanks for looking into this. I'll open a JIRA issue now that I've received my updated password.

Florent


regards, toby

On 9/7/06, Florent Guillaume <[EMAIL PROTECTED]> wrote:
I'm posting here because at the moment I can't login to Jira (seems
my account was reset or something, and "forgotten password" seems to
send email by pigeon carrier).

I have a versioning bug in the presence of transactions. It's hard to
reproduce and seems memory-layout dependent.
At the moment I only have a jython testcase, see below. This is with
a svn checkout from today.
If developers can't mirror that in a pure java testcase I'll try to
do that myself, but I wanted to get the info out asap.
Basically the program does create a node and subnode and do some
checkins, checkouts, restore, modifications, in successive transactions.

The program log and stack trace is:

start 1
node a44e6556-728d-4970-a635-5ff7d2a38f2f
commit 1
start 2
commit 2
start 3
commit 3
javax.transaction.xa.XAException
         at org.apache.jackrabbit.core.TransactionContext.prepare
(TransactionContext.java:138)
         at org.apache.jackrabbit.core.XASessionImpl.commit
(XASessionImpl.java:313)
         File "debug1.py", line 126, in doit
         File "debug1.py", line 159, in ?
Caused by: org.apache.jackrabbit.core.TransactionException: Unable to
prepare transaction.
         at
org.apache.jackrabbit.core.state.XAItemStateManager.prepare
(XAItemStateManager.java:159)
         at org.apache.jackrabbit.core.TransactionContext.prepare
(TransactionContext.java:121)
         ... 22 more
Caused by: org.apache.jackrabbit.core.state.StaleItemStateException:
a44e6556-728d-4970-a635-5ff7d2a38f2f/{http://www.jcp.org/jcr/1.0}
isCheckedOut has been modified externally
         at org.apache.jackrabbit.core.state.SharedItemStateManager
$Update.begin(SharedItemStateManager.java:546)
         at
org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate
(SharedItemStateManager.java:717)
         at
org.apache.jackrabbit.core.state.XAItemStateManager.prepare
(XAItemStateManager.java:151)
         ... 23 more
javax.transaction.xa.XAException: javax.transaction.xa.XAException

Note that the mentionned property (here, isCheckedOut) has changed
when I was cutting down on the program size to get a simpler
testcase. It's not necessarily a "system" property, and sometimes it
was property of the subnode created under the main node.

Test program is attached.
I'm using java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112)
Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing)

Any feedback welcome.

Florent




--
Florent Guillaume, Nuxeo (Paris, France)   Director of R&D
+33 1 40 33 71 59   http://nuxeo.com   [EMAIL PROTECTED]










--
Florent Guillaume, Nuxeo (Paris, France)   Director of R&D
+33 1 40 33 71 59   http://nuxeo.com   [EMAIL PROTECTED]
##############################################################################
#
# Copyright (c) 2006 Nuxeo and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
# Author: Florent Guillaume <[EMAIL PROTECTED]>
# $Id: debug1.py 48864 2006-09-11 13:19:46Z fguillaume $
"""Testcase to debug JCR bug.

Can be run through following script:

jython=$HOME/Java/jython-2.1
jars=$HOME/Java/lib
cp=$jars/commons-collections-3.1.jar
cp=$cp:$jars/concurrent-1.3.4.jar
cp=$cp:$jars/derby-10.1.1.0.jar
cp=$cp:$jars/geronimo-spec-jta-1.0-M1.jar
cp=$cp:$jars/jackrabbit-core-1.1-SNAPSHOT.jar
cp=$cp:$jars/jackrabbit-jcr-commons-1.1-SNAPSHOT.jar
cp=$cp:$jars/jcr-1.0.jar
cp=$cp:$jars/junit-3.8.1.jar
cp=$cp:$jars/log4j-1.2.8.jar
cp=$cp:$jars/lucene-1.4.3.jar
cp=$cp:$jars/slf4j-log4j12-1.0.jar
cp=$cp:$jars/xercesImpl-2.6.2.jar
cp=$cp:$jars/xmlParserAPIs-2.0.2.jar
java -Dpython.home=$jython \
    -classpath $jython/jython.jar:$cp:$CLASSPATH \
    org.python.util.jython "$@"

Pass as an argument the repository path.
"""

import sys

from javax.jcr import SimpleCredentials
from javax.transaction.xa import XAResource
from javax.transaction.xa import XAException
from javax.transaction.xa import Xid

from org.apache.jackrabbit.core import TransientRepository

try:
    True
except NameError:
    True = 1
    False = 0


class DummyXid(Xid):
    def getBranchQualifier(self):
        return []
    def getFormatId(self):
        return 0
    def getGlobalTransactionId(self):
        return []


class Dummy:
    # Class needed because the bug is memory-layout dependent.
    def foo(self): pass


def doit(session):
    root = session.getRootNode()

    # Transaction setup
    workspace = session.getWorkspace()
    xaresource = session.getXAResource()

    ################################################## T1

    print 'start 1'
    xid1 = DummyXid()
    xaresource.start(xid1, XAResource.TMNOFLAGS)

    # Create node, subnode, set props
    node = root.addNode('blob', 'nt:unstructured')
    node.addMixin('mix:versionable')
    print 'node', node.getUUID()
    node.addNode('sub', 'nt:unstructured')
    root.save()
    node.setProperty('youpi', 'yo')
    root.save()

    print 'commit 1'
    xaresource.end(xid1, XAResource.TMSUCCESS)
    xaresource.commit(xid1, True)

    ################################################## T2

    print 'start 2'
    xid2 = DummyXid()
    xaresource.start(xid2, XAResource.TMNOFLAGS)

    # checkin + checkout
    node.checkin()
    node.checkout()
    root.save()

    print 'commit 2'
    xaresource.end(xid2, XAResource.TMSUCCESS)
    xaresource.commit(xid2, True)

    ################################################## T3

    print 'start 3'
    xid3 = DummyXid()
    xaresource.start(xid3, XAResource.TMNOFLAGS)

    # restore
    node.restore(node.getBaseVersion(), True)
    node.checkout()
    # modify subnode
    node.getNode('sub').setProperty('foo', '3') # needed for crash
    root.save()

    print 'commit 3'
    xaresource.end(xid3, XAResource.TMSUCCESS)
    xaresource.commit(xid3, True)

    ################################################## T4

    print 'start 4'
    xid4 = DummyXid()
    xaresource.start(xid4, XAResource.TMNOFLAGS)

    # checkin + checkout
    node.checkin()
    node.checkout()
    # modify node, subnode
    node.setProperty('youpi', 'ho') # needed for crash
    node.getNode('sub').setProperty('foo', '4') # needed for crash
    root.save()

    print 'commit 4'
    xaresource.end(xid4, XAResource.TMSUCCESS)
    xaresource.commit(xid4, True)

    print 'done'


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print >>sys.stderr, "Usage: debug1.py <repopath>"
        sys.exit(1)
    repopath = sys.argv[1]
    repoconf = repopath+'.xml'

    repository = TransientRepository(repoconf, repopath)
    credentials = SimpleCredentials('username', 'password')
    session = repository.login(credentials, 'default')
    try:
        doit(session)
    finally:
        session.logout()

    sys.stdout.flush()

Reply via email to