[
https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483538
]
Martijn Hendriks commented on JCR-798:
--------------------------------------
We have finally found the cause of the CME.
Consider the following scenario: Session A registers an EventListener B which
uses A to process received events. Session A then logs out, and gets the
Iterator in the LocalItemStateManager.dispose method. Then another thread
modifies the repository and triggers the observation mechanism. EventListener B
receives events, and processes them using Session A. This modifies the cache of
Session A, and a CME is thrown.
This scenario is caused by the fact that in the SessionImpl.logout the
Workspace (including ObservationManager) is disposed of after the disposal of
the SessionItemStateManager. A possible fix would be to swap the order there.
I cannot find in the spec whether this is a valid use case of the JCR. I can
image, however, that it is because otherwise each EventListener needs to create
it's own session in order to to something with the events.
regards,
Martijn
> ConcurrentModificationException during logout
> ---------------------------------------------
>
> Key: JCR-798
> URL: https://issues.apache.org/jira/browse/JCR-798
> Project: Jackrabbit
> Issue Type: Bug
> Components: core
> Environment: Jackrabbit 1.2.1
> Reporter: Martijn Hendriks
> Assigned To: Stefan Guggisberg
> Fix For: 1.3
>
>
> We regularly get the following exception:
> java.util.ConcurrentModificationException
> at
> org.apache.commons.collections.map.AbstractReferenceMap$ReferenceEntrySetIterator.checkMod(AbstractReferenceMap.java:761)
> at
> org.apache.commons.collections.map.AbstractReferenceMap$ReferenceEntrySetIterator.hasNext(AbstractReferenceMap.java:735)
> at
> java.util.Collections$UnmodifiableCollection$1.hasNext(Collections.java:1009)
> at
> java.util.Collections$UnmodifiableCollection$1.hasNext(Collections.java:1009)
> at
> org.apache.jackrabbit.core.state.LocalItemStateManager.dispose(LocalItemStateManager.java:341)
> at
> org.apache.jackrabbit.core.WorkspaceImpl.dispose(WorkspaceImpl.java:170)
> at
> org.apache.jackrabbit.core.SessionImpl.logout(SessionImpl.java:1225)
> at
> org.apache.jackrabbit.core.XASessionImpl.logout(XASessionImpl.java:379)
> Two causes for this exception have been identified:
> (Taken from an email to the dev-list from Marcel Reutegger):
> > - session A reads some items I
> > - session B transiently removes items in I
> > - session A logs out and starts to iterate over I in LocalItemStateManager
> > (LISM)
> > - session B saves changes and removed items are evicted from A's LISM
> > - session A gets concurrent modification exception
> Another scenario is the following:
> - Session A gets the iterator of the values of (the primary cache of) an
> ItemStateReferenceCache in LocalItemStateManager.dispose.
> - Session B then does something that triggers the CacheManager.
> - The CacheManager then calls resizeAll, and evicts some items from the
> secondary cache of the ItemStateReferenceCache of which the
> LocalItemStateManager has a values iterator.
> - The garbage collector then runs and evicts the removed items also from the
> primary cache, which effectively modifies the set over which is iterated.
> Regards,
> Martijn Hendriks
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.