myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jakob Korherr <jakob.korh...@gmail.com>
Subject Re: ConcurrentModificationException in RequestMap.getAttributeNames
Date Fri, 09 Apr 2010 09:57:50 GMT
Hi Michael,

I just took a look at this problem and it seems to be one of tomcat. I also
checked out the tomcat 6.0.24 branch to find the code that causes the
exception.

The main problem is that the request map is altered during it is processed
with an Iterator in org.apache.catalina.util.Enumerator -->
java.util.ConcurrentModificationException.

Here is some code from tomcat that shows this conclusion:

org.apache.catalina.connector.Request.getAttributeNames looks like this:

public Enumeration getAttributeNames() {
    // cut for clarity
    return new Enumerator(attributes.keySet(), true);
}

So this code wants to create a new Enumerator with the keySet of the request
attributes. It also tells the Enumerator to clone the keySet before
generating the Iterator internally. The code that does the cloning can be
found in org.apache.catalina.util.Enumerator:

public Enumerator(Iterator iterator, boolean clone) {
        super();
        if (!clone) {
            this.iterator = iterator;
        } else {
            List list = new ArrayList();
            while (iterator.hasNext()) {
                list.add(iterator.next());  // line 101: this is the place
where the ConcurrentModificationException happens
            }
            this.iterator = list.iterator();
        }
    }

So the constructor goes through the given Iterator (from the keySet of the
request map) and creates an ArrayList out of it. The problem is now that if
another thread alters the request map during this creation, you will get the
ConcurrentModificationException. Of course, this is very rare and
furthermore I guess the cloning was added to minimize the chance of a
ConcurrentModificationException, but it still can happen.

If you really want to eleminate this problem, thread synchronizing has to be
introduced here.

Regards,
Jakob


2010/4/9 Michael Heinen <mhn4dev@googlemail.com>

> Hi,
>
> I found followoing exception a few times in my tomcat log after running a
> JMeter stresstest some hours with a few hundred users.
> Any ideas about a ConcurrentModificationException during
> RequestMap.getAttributeNames() ?
>
> [2010-04-07 09:00:59,653] http-8080-6 [ERROR]
> [6799FA3FDEBB49F294E54657DB099957] servlets.FacesServletWrapper service:
> Caught exception in the FacesServletWrapper:
> javax.servlet.ServletException: java.util.ConcurrentModificationException
>    at
> javax.faces.webapp._ErrorPageWriter.throwException(_ErrorPageWriter.java:549)
>    at
> javax.faces.webapp.FacesServlet.handleLifecycleException(FacesServlet.java:293)
>    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:187)
>    at
> com.foo.client.web.servlets.FacesServletWrapper.service(FacesServletWrapper.java:124)
>    at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
>    at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>    at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
>    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
>    at
> org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
>    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
>    at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>    at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>    at
> org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:384)
>    at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>    at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>    at com.foo.client.web.filters.LoginFilter.doFilter(LoginFilter.java:183)
>    at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>    at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>    at
> com.foo.client.web.filters.EncodingFilter.doFilter(EncodingFilter.java:49)
>    at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>    at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>    at com.foo.client.web.filters.TimerFilter.doFilter(TimerFilter.java:71)
>    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.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:465)
>    at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
>    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:298)
>    at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
>    at
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
>    at
> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
>    at java.lang.Thread.run(Thread.java:619)
> Caused by: javax.faces.FacesException:
> java.util.ConcurrentModificationException
>    at
> javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:166)
>    at
> javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:293)
>    at
> javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:172)
>    at
> javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:293)
>    at
> javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:172)
>    at
> javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:293)
>    at
> javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:172)
>    at
> javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:293)
>    at
> javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:172)
>    at
> javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:293)
>    at
> org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:226)
>    at
> org.ajax4jsf.component.AjaxViewRoot.processValidators(AjaxViewRoot.java:463)
>    at
> org.apache.myfaces.lifecycle.ProcessValidationsExecutor.execute(ProcessValidationsExecutor.java:32)
>    at
> org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
>    at
> org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
>    at
> org.apache.myfaces.custom.ppr.PPRLifecycleWrapper.execute(PPRLifecycleWrapper.java:68)
>    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:178)
>    ... 32 more
> Caused by: java.util.ConcurrentModificationException
>    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
>    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
>    at org.apache.catalina.util.Enumerator.<init>(Enumerator.java:101)
>    at org.apache.catalina.util.Enumerator.<init>(Enumerator.java:67)
>    at
> org.apache.catalina.connector.Request.getAttributeNames(Request.java:962)
>    at
> org.apache.catalina.connector.RequestFacade.getAttributeNames(RequestFacade.java:278)
>    at
> org.apache.myfaces.context.servlet.RequestMap.getAttributeNames(RequestMap.java:66)
>    at
> org.apache.myfaces.util.AbstractAttributeMap$AbstractAttributeIterator.<init>(AbstractAttributeMap.java:196)
>    at
> org.apache.myfaces.util.AbstractAttributeMap$AbstractAttributeIterator.<init>(AbstractAttributeMap.java:194)
>    at
> org.apache.myfaces.util.AbstractAttributeMap$KeyIterator.<init>(AbstractAttributeMap.java:224)
>    at
> org.apache.myfaces.util.AbstractAttributeMap$KeyIterator.<init>(AbstractAttributeMap.java:224)
>    at
> org.apache.myfaces.util.AbstractAttributeMap$KeySet.iterator(AbstractAttributeMap.java:177)
>    at
> org.richfaces.component.ClonedObjectResolver.resolveCloned(ClonedObjectResolver.java:92)
>    at
> org.richfaces.component.ClonedObjectResolver.getValue(ClonedObjectResolver.java:61)
>    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
>    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
>    at
> org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:140)
>    at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:61)
>    at org.apache.el.parser.AstValue.getValue(AstValue.java:107)
>    at
> org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
>    at
> org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
>    at
> javax.faces.component._ComponentUtils.getExpressionValue(_ComponentUtils.java:236)
>    at
> javax.faces.component.UIComponentBase.getExpressionValue(UIComponentBase.java:1176)
>    at
> javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:1251)
>    at
> org.apache.myfaces.custom.htmlTag.AbstractHtmlTag.isRendered(AbstractHtmlTag.java:84)
>    at
> org.apache.myfaces.custom.datalist.AbstractHtmlDataList.processChildren(AbstractHtmlDataList.java:149)
>    at
> org.apache.myfaces.custom.datalist.AbstractHtmlDataList.processValidators(AbstractHtmlDataList.java:108)
>    at
> javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:726)
>    at
> javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:726)
>    at
> javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:726)
>    at
> javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:726)
>    at
> javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:726)
>    at javax.faces.component.UIForm.processValidators(UIForm.java:82)
>    at
> org.ajax4jsf.component.AjaxViewRoot$3.invokeContextCallback(AjaxViewRoot.java:447)
>    at
> org.ajax4jsf.component.ContextCallbackWrapper.invokeContextCallback(ContextCallbackWrapper.java:44)
>    at
> javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:163)
>    ... 48 more
>
> I do not start a new thread during request processing and therefore I don't
> have any idea about the concurrent modification on Request level.
>
> Is this rather an application issue, a myfaces issue, a richfaces issue or
> a tomcat issue?
> I can't reproduce this manually of course.
>
> Environment:
> myFaces 1.2.8
> richfaces 3.3.3
> jsps, no facelets
> Tomcat 6.0.24
> jdk 1.6.0.16
>
> Michael
>
>


-- 
Jakob Korherr

blog: http://www.jakobk.com
twitter: http://twitter.com/jakobkorherr
work: http://www.irian.at

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message