[
https://issues.apache.org/jira/browse/SLING-1290?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12802240#action_12802240
]
Ian Boston commented on SLING-1290:
-----------------------------------
setFast(true) is in the constructor, and there are no calls within the
constructor that would cause a reference to "this" to leak out and be used by
another thread prior to setFast(true).
According to the doc, once setFast(true) is called, the FastTreeMap is thread
safe
Looking for the code for CollectionViewIterator.hasNext() I see
public boolean hasNext() {
if (expected != map) {
throw new ConcurrentModificationException();
}
return iterator.hasNext();
}
Ie if the map that was in existence when the iterator was created is changed,
then we get a concurrent modification exception, indicating get() access to the
fast tree map is thread safe, but iterator access is not. This is the same as
TreeMap (Javadoc there warns of the iterator issue)
IIRC the TreeMap was used to maintain an order, and FastTreeMap for thread
safety of read and write operations. There is no ordered ConcurrentHashMap
which doesnt have fast-fail iterators
If we want to solve this, we will need to change all the loops to take a copy
of all values prior to iterating, or keep a readonly copy of the array used for
iterating, updated after each update, taking an atomic reference prior to any
iteration.
WDYT ?
> Concurrent modification exception on startup
> --------------------------------------------
>
> Key: SLING-1290
> URL: https://issues.apache.org/jira/browse/SLING-1290
> Project: Sling
> Issue Type: Bug
> Components: JCR
> Affects Versions: JCR Resource 2.0.6
> Reporter: Carsten Ziegeler
>
> java.util.ConcurrentModificationException
> at
> org.apache.commons.collections.FastTreeMap$CollectionView$CollectionViewIterator.hasNext(FastTreeMap.java:745)
> at
> org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry.getResourceProviders(ResourceProviderEntry.java:547)
> at
> org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry.getResourceProviders(ResourceProviderEntry.java:529)
> at
> org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry.access$000(ResourceProviderEntry.java:50)
> at
> org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry$1.<init>(ResourceProviderEntry.java:167)
> at
> org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry.listChildren(ResourceProviderEntry.java:142)
> at
> org.apache.sling.jcr.resource.internal.JcrResourceResolver.listChildren(JcrResourceResolver.java:458)
> at
> org.apache.sling.servlets.resolver.internal.helper.ResourceCollector.getWeightedResources(ResourceCollector.java:193)
> at
> org.apache.sling.servlets.resolver.internal.helper.ResourceCollector.getServlets(ResourceCollector.java:173)
> at
> org.apache.sling.servlets.resolver.internal.SlingServletResolver.getServlet(SlingServletResolver.java:457)
> at
> org.apache.sling.servlets.resolver.internal.SlingServletResolver.resolveServlet(SlingServletResolver.java:205)
> at
> org.apache.sling.engine.impl.request.RequestData.initServlet(RequestData.java:216)
> at
> org.apache.sling.engine.impl.SlingMainServlet.service(SlingMainServlet.java:298)
> at
> org.apache.sling.engine.impl.SlingMainServlet.service(SlingMainServlet.java:189)
> at
> org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90)
> at
> org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:109)
> at
> org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:75)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
> at
> org.apache.sling.launchpad.base.webapp.SlingServletDelegate.service(SlingServletDelegate.java:276)
> at
> org.apache.sling.launchpad.webapp.SlingServlet.service(SlingServlet.java:129)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> at
> com.day.crx.launchpad.filters.CRXLaunchpadLicenseFilter.doFilter(CRXLaunchpadLicenseFilter.java:96)
> at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
> at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
> at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
> at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
> at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
> at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
> at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
> at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
> at
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
> at
> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
> at java.lang.Thread.run(Thread.java:637)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.