Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-41971

Server side parallel rendering request.getAttributeNames() can potentially cause java.util.ConcurrentModificationException

Details

    Description

      ThreadLocalFacadeHttpServletRequestWrapper/ThreadLocalFacadeServletRequestWrapper.getAttributeNames() is eventually calling threadlocal original request object getAttributeNames() which internally does a copy on the attribute map's keyset, this is causing a keyset iterator iterating.

      In the mean time, if another concurrent renderring portlet finishes fast enough, join back to original worker thread starts to merge back shared attributes. This may modify the original request object's attribute map while the parallel rendering thread is still in the middle of the keyset iterator iterating.

      Then on next keyset iterator accessing, will trigger a java.util.ConcurrentModificationException. For example:

      java.util.ConcurrentModificationException
      	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
      	at java.util.HashMap$KeyIterator.next(HashMap.java:960)
      	at java.util.AbstractCollection.addAll(AbstractCollection.java:341)
      	at org.apache.catalina.connector.Request.getAttributeNames(Request.java:1036)
      	at org.apache.catalina.connector.RequestFacade.getAttributeNames(RequestFacade.java:300)
      	at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.<init>(ApplicationHttpRequest.java:927)
      	at org.apache.catalina.core.ApplicationHttpRequest.getAttributeNames(ApplicationHttpRequest.java:243)
      	at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.<init>(ApplicationHttpRequest.java:927)
      	at org.apache.catalina.core.ApplicationHttpRequest.getAttributeNames(ApplicationHttpRequest.java:243)
      	at com.liferay.portal.servlet.ThreadLocalFacadeHttpServletRequestWrapper.getAttributeNames(ThreadLocalFacadeHttpServletRequestWrapper.java:90)
      	at javax.servlet.ServletRequestWrapper.getAttributeNames(ServletRequestWrapper.java:85)
      	at com.liferay.portal.kernel.portlet.RestrictPortletServletRequest.getAttributeNames(RestrictPortletServletRequest.java:68)
      	at javax.servlet.ServletRequestWrapper.getAttributeNames(ServletRequestWrapper.java:85)
      	at com.liferay.portlet.PortletRequestImpl.getAttributeNames(PortletRequestImpl.java:166)
      	at com.liferay.portlet.helloworld.HelloWorldPortlet.doView(HelloWorldPortlet.java:38)
      	at javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:328)
      	at javax.portlet.GenericPortlet.render(GenericPortlet.java:233)
      	at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:103)
      	at com.liferay.portlet.ScriptDataPortletFilter.doFilter(ScriptDataPortletFilter.java:55)
      	at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:100)
      

      To fix this, we need to force ThreadLocalFacadeHttpServletRequestWrapper/ThreadLocalFacadeServletRequestWrapper.getAttributeNames() to be protected by parallel rendering merge lock.

      Attachments

        Issue Links

          Activity

            People

              brian.chan Brian Chan
              shuyang.zhou Shuyang Zhou
              Kiyoshi Lee Kiyoshi Lee
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                8 years, 49 weeks ago

                Packages

                  Version Package
                  6.2.1 CE GA2
                  6.2.X EE
                  7.0.0 M1