On 07.02.2019 10:54, Jane E. Doe wrote:
Good afternoon

Our application uses Jackrabbit 2.18 and Oak 1.10 as content repository for
document storage. Jackrabbit and the backend of our application are running
on Tomcat 7 server on a Linux platform. End users access the application via
Internet Explorer. One of the main tasks is editing documents with Microsoft
Word 2010, and uploading them directly to the server via WEBDAV. However,
there seems to be a locking problem.

From what we observe in the logs, the workflow is the following:
- Several PROPFIND and GET requests are exchanged, e.g fetching the
workspace name, json representation of the document node and jcr:content
json
- what seems suspicous to me is that jcr:isCheckedOut is false
- Ms Word executes a LOCK request, jackrabbit locks the document node and
sends a lock token in the HTTP response header, for example:
Lock-Token:
<opaquelocktoken:dccce564-412e-11e1-b969-00059a3c7a00:317e98f0-2a8b-4ed8-9093-1ba2dbab7cb2-G>
Lockdiscovery response:
<D:prop xmlns:D="DAV:">
    <D:lockdiscovery>
       <D:activelock>
          <D:lockscope>
             <D:exclusive />
          </D:lockscope>
          <D:locktype>
             <D:write />
          </D:locktype>
          <D:depth>infinity</D:depth>
          <D:timeout>Second-3599</D:timeout>
          <D:owner>foobar</D:owner>
          <D:locktoken>
<D:href>opaquelocktoken:dccce564-412e-11e1-b969-00059a3c7a00:317e98f0-2a8b-4ed8-9093-1ba2dbab7cb2-G</D:href>
          </D:locktoken>
       </D:activelock>
    </D:lockdiscovery>
</D:prop>

- jcr:lockIsDeep and jcr:lockOwner properties are added to the node.
jcr:uuid is written in the locks file maintained by jackrabbit
- A JcrLock object is created, and with the debugger we can see it being
stored in the lockMap data structure of
org.apache.jackrabbit.jcr2spi.lock.LockManagerImpl. NodeState is INVALIDATED
(status = 0).

- When the user edits the document and tries to save the changes, a second
(refresh) LOCK request is sent. The lock token is sent in the If-Header of
the request:
- The call goes to the AbstractWebdavServlet.doLock() method, and then
jackrabbit tries to obtain the existing lock by calling
DavResourceImpl.getLock()
- However, the lockMap structure of
org.apache.jackrabbit.jcr2spi.lock.LockManagerImpl is empty! I checked the
code, and we're quite sure that we do not call session.logout() anywhere,
which might have purged the lockMap according to the Javadocs
- BTW, NodeState is EXISTING (state = 0). So, even if the map were
containing the lock entry, we wouldn't have obtained out lock because
NodeState is different than the stored key. Right?
- In the logs, we see the Precondition Failed Exception:

org.apache.jackrabbit.webdav.DavException: Precondition Failed
        at
org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.doLock(AbstractWebdavServlet.java:912)
        at 
foo.bar.servlet.package.MyWebdavServlet.doLock(MyWebdavServlet.java:232)
        at
org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.execute(AbstractWebdavServlet.java:389)
        at
org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.service(AbstractWebdavServlet.java:305)
        at 
foo.bar.servlet.package.MyWebdavServlet.service(MyWebdavServlet.java:89)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)

There's another Error in the logs preceding the precondition Failed
Exception. Afaik, it doesn't hinder the application flow much:

rg.apache.jackrabbit.webdav.simple.DavResourceImpl: unable to calculate
parent set {BMT|ubsdav|||AAfJGtp9mOrF9BBZ||en_US - |}
javax.jcr.UnsupportedRepositoryOperationException: JCR-1104
        at 
org.apache.jackrabbit.jcr2spi.NodeImpl.getSharedSet(NodeImpl.java:1288)
        at
org.apache.jackrabbit.webdav.simple.DavResourceImpl.getParentElements(DavResourceImpl.java:853)
        at
org.apache.jackrabbit.webdav.simple.DavResourceImpl.initProperties(DavResourceImpl.java:346)
        at
org.apache.jackrabbit.webdav.simple.DavResourceImpl.getProperty(DavResourceImpl.java:295)
        at
org.apache.jackrabbit.webdav.MultiStatusResponse.<init>(MultiStatusResponse.java:186)
        at
org.apache.jackrabbit.webdav.MultiStatus.addResourceProperties(MultiStatus.java:61)
        at
org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.doPropFind(AbstractWebdavServlet.java:574)
        at
org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.execute(AbstractWebdavServlet.java:362)
        at
org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.service(AbstractWebdavServlet.java:305)

Have you got any advice on how I can fix the Refresh LOCK request?

Many thanks in advance!
Jane E.

Wow - that's already a detailed analysis.

Looking at the last part:

> There's another Error in the logs preceding the precondition Failed
> Exception. Afaik, it doesn't hinder the application flow much:
>
> rg.apache.jackrabbit.webdav.simple.DavResourceImpl: unable to calculate
> parent set {BMT|ubsdav|||AAfJGtp9mOrF9BBZ||en_US - |}
> javax.jcr.UnsupportedRepositoryOperationException: JCR-1104
> at org.apache.jackrabbit.jcr2spi.NodeImpl.getSharedSet(NodeImpl.java:1288)
>    at
> org.apache.jackrabbit.webdav.simple.DavResourceImpl.getParentElements(DavResourceImpl.java:853)
>    at
> org.apache.jackrabbit.webdav.simple.DavResourceImpl.initProperties(DavResourceImpl.java:346)
>    at

...that looks pretty serious to me. AFAIU, that means that a PROPFIND request will fail with a 5xx that should succeed.

Would be good to understand and fix that first...

Best regards, Julian

Reply via email to