You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by "Martijn Hendriks (JIRA)" <ji...@apache.org> on 2007/03/19 10:16:32 UTC

[jira] Created: (JCR-798) ConcurrentModificationException during logout

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


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.


[jira] Updated: (JCR-798) ConcurrentModificationException during logout

Posted by "Jukka Zitting (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jukka Zitting updated JCR-798:
------------------------------

    Attachment: currentObservationSession.patch

For the record, the attached patch implements a simple check that prevents an observation listener from accessing the session it was registered with. I don't think the overhead is worth the benefit, so I won't apply this patch, but it's here in case people start falling into that concurrency trap.

> 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
>
>         Attachments: currentObservationSession.patch
>
>
> 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.


[jira] Reopened: (JCR-798) ConcurrentModificationException during logout

Posted by "Martijn Hendriks (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Martijn Hendriks reopened JCR-798:
----------------------------------


Unfortunately, the CME still occurs:

java.util.ConcurrentModificationException
        at org.apache.commons.collections.map.AbstractReferenceMap$ReferenceEntrySetIterator.checkMod(AbstractReferenceM
ap.java:761)
        at org.apache.commons.collections.map.AbstractReferenceMap$ReferenceEntrySetIterator.nextEntry(AbstractReference
Map.java:770)
        at org.apache.commons.collections.map.AbstractReferenceMap$ReferenceValuesIterator.next(AbstractReferenceMap.jav
a:829)
        at org.apache.commons.collections.map.AbstractReferenceMap$ReferenceValues.toArray(AbstractReferenceMap.java:544)
        at java.util.Collections$UnmodifiableCollection.toArray(Collections.java:1002)
        at java.util.Collections$UnmodifiableCollection.toArray(Collections.java:1002)
        at org.apache.jackrabbit.core.state.LocalItemStateManager.dispose(LocalItemStateManager.java:343)
        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)

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.


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Martijn Hendriks (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483090 ] 

Martijn Hendriks commented on JCR-798:
--------------------------------------

It seems to me that the only way of avoiding such concurrent modifications is to have some form of synchronization. For instance, having a read-write lock in the LISM that serializes the calls to dispose and the ItemStateListener methods could prevent the first scenario as sketched above. This, however, does not solve the second scenario. I.e., when an item is to be evicted from a MLRUItemStateCache, it must be certain that nobody iterates over the related ItemStateReferenceMap (via the ItemStateReferenceCache).

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.


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483638 ] 

Stefan Guggisberg commented on JCR-798:
---------------------------------------

> Reading Martijn's description it seems that the problem is simply 
> that the event listener is not automatically unregistered when the 
> session is closed. Session.logout() should always unregister all 
> listeners associated with that session, after which the described 
> problem shouldn't occur.

event listeners registered by a session are already automatically 
unregistered on Session.logout(). the core issue here is that
the same session is used by multiple threads (event dispatcher 
and application thread). 

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


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Jukka Zitting (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483642 ] 

Jukka Zitting commented on JCR-798:
-----------------------------------

> event listeners registered by a session are already automatically
> unregistered on Session.logout().

Looking at the code it seems like the even listeners are unregistered only after the item state and item managers have been disposed. That order should probably at least be changed.

> the core issue here is that the same session is used by multiple
> threads (event dispatcher and application thread).

I don't think we can avoid that with the JCR observation design. At least the event dispatcher and the application thread need to share the local namespace mappings of the session.

I agree that it's an application problem if the event *listener* uses the same session that was used to register it. Such a solution is almost always incorrect, though I can see unwary developers easily falling into that trap. Perhaps we should log a warning or even throw an exception if we detect a call like Session.getItem() being issued from an event listener registered by the same session?


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


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483623 ] 

Stefan Guggisberg commented on JCR-798:
---------------------------------------

martjin, thanks for sharing this. 

> 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 confirms my assumption. session A is actually used by 2 
separate threads: 

1. the thread that's logging out session A
2. the thread that is dispatching the events to the event listener
    (which in turn is using session A aswell)

> I cannot find in the spec whether this is a valid use case of the JCR. 

"7.5 Thread-Safety Requirements" states that you cannot assume Session
being thread-safe. 

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

only if your EventListener interacts with the repository. that's just one, but 
certainly not the only use case. 

wrt your suggested fix (swapping the order of disposing the workspace/SISM):
while that would probably fix this issue i am somehow reluctant to apply it.
i am concerned that this could possibly cause new, more serious issues
since the order of those calls is quite delicate.

i am tempted to resolve this issue as "Won't fix" or "Invalid" since it's imo caused
by improper session usage. wdyt?

cheers
stefan

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


[jira] Resolved: (JCR-798) ConcurrentModificationException during logout

Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Stefan Guggisberg resolved JCR-798.
-----------------------------------

       Resolution: Fixed
    Fix Version/s: 1.3

fixed in svn r519892.

since i haven't been able to reproduce the issue i couldn't verify the fix.
please reopen this issue if the ConcurrentModificationException still
occur on session logout.

thanks for reporting this issue,
cheers
stefan

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


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Martijn Hendriks (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12484203 ] 

Martijn Hendriks commented on JCR-798:
--------------------------------------

I am not familiar with the mechanics of remapping a namespace as Jukka mentioned, but isn't it possible to apply a namespace remapping to two sessions and use one in the application thread and one in the observation thread? If there is no usecase of two threads sharing a session then I guess that the issue can indeed be resolved as "Won't fix" or "invalid" as Stefan suggested.
I don't know whether trying to detect this kind of usage of sessions is worth the overhead. Maybe the "nondeterministic detection" by the CME that is in place right now is enough?

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.


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483099 ] 

Stefan Guggisberg commented on JCR-798:
---------------------------------------

i don't think that the second scenario (i.e. garbage collector interfering while iterating over ReferenceMap entries) is realistic since this should IMO be taken care of by the commons-collections ReferenceMap class. since ReferenceMap is being heavily used in jackrabbit's core we would see a lot more issues like this if that wouldn't be the case. 

i think that marcel's scenario and/or improper sharing of Session instances are the most plausible explanations for this issue.

since i've never come across this issue myself i'd like to be able to reproduce it in order to further analyze it. 
martjin, could you perhaps provide a simple test-case?

cheers
stefan

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


[jira] Assigned: (JCR-798) ConcurrentModificationException during logout

Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Stefan Guggisberg reassigned JCR-798:
-------------------------------------

    Assignee: Stefan Guggisberg

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


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Jukka Zitting (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12483625 ] 

Jukka Zitting commented on JCR-798:
-----------------------------------

Reading Martijn's description it seems that the problem is simply that the event listener is not automatically unregistered when the session is closed. Session.logout() should always unregister all listeners associated with that session, after which the described problem shouldn't occur.

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


[jira] Commented: (JCR-798) ConcurrentModificationException during logout

Posted by "Martijn Hendriks (JIRA)" <ji...@apache.org>.
    [ 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.


[jira] Resolved: (JCR-798) ConcurrentModificationException during logout

Posted by "Jukka Zitting (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/JCR-798?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jukka Zitting resolved JCR-798.
-------------------------------

    Resolution: Fixed

Fixed in revision 529913 by explicitly removing all registered event listeners at the beginning of the logout() method.

The EventConsumer class calls session.getAccessManager().isGranted() which in turn (depending on the configured AccessManager) can access session internals like the hierarchy and item state managers. This could previously happen in parallel with the logout() method.

> 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
>
>         Attachments: currentObservationSession.patch
>
>
> 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.