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/01/19 12:06:29 UTC
[jira] Created: (JCR-713) ConcurrentModificationException during
registration of nodetypes
ConcurrentModificationException during registration of nodetypes
----------------------------------------------------------------
Key: JCR-713
URL: https://issues.apache.org/jira/browse/JCR-713
Project: Jackrabbit
Issue Type: Bug
Components: core
Affects Versions: 1.1.1
Reporter: Martijn Hendriks
During the registration of a set of nodetypes this exception may be encountered:
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 org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.notifyRegistered(NodeTypeRegistry.java:1750)
at org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.registerNodeTypes(NodeTypeRegistry.java:223)
It seems that the copying of the listeners triggered this exception:
private void notifyRegistered(QName ntName) {
// copy listeners to array to avoid ConcurrentModificationException
NodeTypeRegistryListener[] la =
new NodeTypeRegistryListener[listeners.size()];
Iterator iter = listeners.values().iterator();
int cnt = 0;
1750: while (iter.hasNext()) {
la[cnt++] = (NodeTypeRegistryListener) iter.next();
}
for (int i = 0; i < la.length; i++) {
if (la[i] != null) {
la[i].nodeTypeRegistered(ntName);
}
}
}
The methods "notifyReRegistered" and "notifyUnregistered" will probably suffer from the same problem.
Reproduction of this exception may be tricky; it only occurred once in our application. It is probably a race condition: another thread might access the listeners during the copy. It may be helpful to use a debugger and set a breakpoint in the middle of the copy giving other threads the opportunity to access the listeners...
We think that a possible solution is the following:
/**
* Notify the listeners that a node type <code>ntName</code> has been registered.
*/
private void notifyRegistered(QName ntName) {
// copy listeners to array to avoid ConcurrentModificationException
NodeTypeRegistryListener[] la;
synchronized (listeners) {
la = (NodeTypeRegistryListener[]) listeners.values().toArray(new NodeTypeRegistryListener[listeners.size()]);
}
for (int i = 0; i < la.length; i++) {
if (la[i] != null) {
la[i].nodeTypeRegistered(ntName);
}
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] Assigned: (JCR-713) ConcurrentModificationException during
registration of nodetypes
Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/JCR-713?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Stefan Guggisberg reassigned JCR-713:
-------------------------------------
Assignee: Stefan Guggisberg
> ConcurrentModificationException during registration of nodetypes
> ----------------------------------------------------------------
>
> Key: JCR-713
> URL: https://issues.apache.org/jira/browse/JCR-713
> Project: Jackrabbit
> Issue Type: Bug
> Components: core
> Affects Versions: 1.1.1
> Reporter: Martijn Hendriks
> Assigned To: Stefan Guggisberg
>
> During the registration of a set of nodetypes this exception may be encountered:
> 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 org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.notifyRegistered(NodeTypeRegistry.java:1750)
> at org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.registerNodeTypes(NodeTypeRegistry.java:223)
> It seems that the copying of the listeners triggered this exception:
> private void notifyRegistered(QName ntName) {
> // copy listeners to array to avoid ConcurrentModificationException
> NodeTypeRegistryListener[] la =
> new NodeTypeRegistryListener[listeners.size()];
> Iterator iter = listeners.values().iterator();
> int cnt = 0;
> 1750: while (iter.hasNext()) {
> la[cnt++] = (NodeTypeRegistryListener) iter.next();
> }
> for (int i = 0; i < la.length; i++) {
> if (la[i] != null) {
> la[i].nodeTypeRegistered(ntName);
> }
> }
> }
> The methods "notifyReRegistered" and "notifyUnregistered" will probably suffer from the same problem.
> Reproduction of this exception may be tricky; it only occurred once in our application. It is probably a race condition: another thread might access the listeners during the copy. It may be helpful to use a debugger and set a breakpoint in the middle of the copy giving other threads the opportunity to access the listeners...
> We think that a possible solution is the following:
> /**
> * Notify the listeners that a node type <code>ntName</code> has been registered.
> */
> private void notifyRegistered(QName ntName) {
> // copy listeners to array to avoid ConcurrentModificationException
> NodeTypeRegistryListener[] la;
> synchronized (listeners) {
> la = (NodeTypeRegistryListener[]) listeners.values().toArray(new NodeTypeRegistryListener[listeners.size()]);
> }
> for (int i = 0; i < la.length; i++) {
> if (la[i] != null) {
> la[i].nodeTypeRegistered(ntName);
> }
> }
> }
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
[jira] Updated: (JCR-713) ConcurrentModificationException during
registration of nodetypes
Posted by "Jukka Zitting (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/JCR-713?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jukka Zitting updated JCR-713:
------------------------------
Affects Version/s: 1.2.1
> ConcurrentModificationException during registration of nodetypes
> ----------------------------------------------------------------
>
> Key: JCR-713
> URL: https://issues.apache.org/jira/browse/JCR-713
> Project: Jackrabbit
> Issue Type: Bug
> Components: core
> Affects Versions: 1.1.1, 1.2.1
> Reporter: Martijn Hendriks
> Assigned To: Stefan Guggisberg
> Fix For: 1.2.2
>
>
> During the registration of a set of nodetypes this exception may be encountered:
> 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 org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.notifyRegistered(NodeTypeRegistry.java:1750)
> at org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.registerNodeTypes(NodeTypeRegistry.java:223)
> It seems that the copying of the listeners triggered this exception:
> private void notifyRegistered(QName ntName) {
> // copy listeners to array to avoid ConcurrentModificationException
> NodeTypeRegistryListener[] la =
> new NodeTypeRegistryListener[listeners.size()];
> Iterator iter = listeners.values().iterator();
> int cnt = 0;
> 1750: while (iter.hasNext()) {
> la[cnt++] = (NodeTypeRegistryListener) iter.next();
> }
> for (int i = 0; i < la.length; i++) {
> if (la[i] != null) {
> la[i].nodeTypeRegistered(ntName);
> }
> }
> }
> The methods "notifyReRegistered" and "notifyUnregistered" will probably suffer from the same problem.
> Reproduction of this exception may be tricky; it only occurred once in our application. It is probably a race condition: another thread might access the listeners during the copy. It may be helpful to use a debugger and set a breakpoint in the middle of the copy giving other threads the opportunity to access the listeners...
> We think that a possible solution is the following:
> /**
> * Notify the listeners that a node type <code>ntName</code> has been registered.
> */
> private void notifyRegistered(QName ntName) {
> // copy listeners to array to avoid ConcurrentModificationException
> NodeTypeRegistryListener[] la;
> synchronized (listeners) {
> la = (NodeTypeRegistryListener[]) listeners.values().toArray(new NodeTypeRegistryListener[listeners.size()]);
> }
> for (int i = 0; i < la.length; i++) {
> if (la[i] != null) {
> la[i].nodeTypeRegistered(ntName);
> }
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
[jira] Resolved: (JCR-713) ConcurrentModificationException during
registration of nodetypes
Posted by "Stefan Guggisberg (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/jira/browse/JCR-713?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Stefan Guggisberg resolved JCR-713.
-----------------------------------
Resolution: Fixed
Fix Version/s: 1.2.2
fixed in svn r497809.
fixed as suggested with a minor modification:
'synchronized (listeners)' is not necessary since listeners is a SynchronizedMap,
i.e. both values() and toArray() are already synchronized on the instance.
btw: the reason why the listeners array had been manually created & populated
rather than simply calling toArray() was a bug in common-collections-2.1
(http://issues.apache.org/bugzilla/show_bug.cgi?id=25551). it's not obvious
and i should have documented the workaround... however, since jackrabbit moved
on to use common-collections-3.1 in the meantime this workaround is no longer
necessary, i.e. it's safe and perfectly reasonable to use ReferenceMap.values().toArray().
> ConcurrentModificationException during registration of nodetypes
> ----------------------------------------------------------------
>
> Key: JCR-713
> URL: https://issues.apache.org/jira/browse/JCR-713
> Project: Jackrabbit
> Issue Type: Bug
> Components: core
> Affects Versions: 1.1.1
> Reporter: Martijn Hendriks
> Assigned To: Stefan Guggisberg
> Fix For: 1.2.2
>
>
> During the registration of a set of nodetypes this exception may be encountered:
> 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 org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.notifyRegistered(NodeTypeRegistry.java:1750)
> at org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.registerNodeTypes(NodeTypeRegistry.java:223)
> It seems that the copying of the listeners triggered this exception:
> private void notifyRegistered(QName ntName) {
> // copy listeners to array to avoid ConcurrentModificationException
> NodeTypeRegistryListener[] la =
> new NodeTypeRegistryListener[listeners.size()];
> Iterator iter = listeners.values().iterator();
> int cnt = 0;
> 1750: while (iter.hasNext()) {
> la[cnt++] = (NodeTypeRegistryListener) iter.next();
> }
> for (int i = 0; i < la.length; i++) {
> if (la[i] != null) {
> la[i].nodeTypeRegistered(ntName);
> }
> }
> }
> The methods "notifyReRegistered" and "notifyUnregistered" will probably suffer from the same problem.
> Reproduction of this exception may be tricky; it only occurred once in our application. It is probably a race condition: another thread might access the listeners during the copy. It may be helpful to use a debugger and set a breakpoint in the middle of the copy giving other threads the opportunity to access the listeners...
> We think that a possible solution is the following:
> /**
> * Notify the listeners that a node type <code>ntName</code> has been registered.
> */
> private void notifyRegistered(QName ntName) {
> // copy listeners to array to avoid ConcurrentModificationException
> NodeTypeRegistryListener[] la;
> synchronized (listeners) {
> la = (NodeTypeRegistryListener[]) listeners.values().toArray(new NodeTypeRegistryListener[listeners.size()]);
> }
> for (int i = 0; i < la.length; i++) {
> if (la[i] != null) {
> la[i].nodeTypeRegistered(ntName);
> }
> }
> }
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira