Uploaded image for project: 'ServiceMix Components'
  1. ServiceMix Components
  2. SMXCOMP-504

ConcurrentModificationExceptions under heavy load in CXF BC

    XMLWordPrintableJSON

Details

    Description

      Under heavy load ServiceMix throws occasional ConcurrentModificationExceptions with this stack trace:

      Caused by: java.util.ConcurrentModificationException
      at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
      at java.util.AbstractList$Itr.next(AbstractList.java:343)
      at org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:168)
      at org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:160)
      at org.apache.servicemix.cxfbc.CxfBcProvider.process(CxfBcProvider.java:227)
      at org.apache.servicemix.common.AsyncBaseLifeCycle.doProcess(AsyncBaseLifeCycle.java:621)
      at org.apache. servicemix.common.AsyncBaseLifeCycle.processExchange(AsyncBaseLifeCycle.java:575)
      at org.apache.servicemix.common.AsyncBaseLifeCycle.onMessageExchange(AsyncBaseLifeCycle.java:531)
      at org.apache.servicemix.common.SyncLifeCycleWrapper.onMessageExchange(SyncLifeCycleWrapper.java:60)
      at org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBound(DeliveryChannelImpl.java:623)
      at org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlow.java:172)
      at org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.java:16
      

      The reason for this is that the CXF example from the documentation adds the interceptors as a list :

      <cxfbc:inInterceptors>
          <ref bean="LoggingInInterceptor"/>
      </cxfbc:inInterceptors>
      <cxfbc:outInterceptors>
          <ref bean="LoggingOutInterceptor"/>
      </cxfbc:outInterceptors>
      <cxfbc:inFaultInterceptors>
          <ref bean="LoggingInInterceptor"/>
      </cxfbc:inFaultInterceptors>
      <cxfbc:outFaultInterceptors>
          <ref bean="LoggingOutInterceptor"/>
      </cxfbc:outFaultInterceptors>
      

      For example this then gets set as a list when injected by Spring

          List<Interceptor> in = new CopyOnWriteArrayList<Interceptor>();
      // ... SNIP ...
          /**
              * Specifies a list of interceptors used to process requests recieved
              * by the endpoint.
              *
              * @param interceptors   a list of <code>Interceptor</code> objects
              * @org.apache.xbean.Property description="a list of beans configuring interceptors that process incoming requests"
              * */
          public void setInInterceptors(List<Interceptor> interceptors) {
              in = interceptors;
          }
      

      The CopyOnWriteArrayList is lost and can lead to the ConcurrentModificationException.
      One possible solution is to update the Spring configuration for the interceptors to wrap it in a CopyOnWriteArrayList.

      <property name="inInterceptors">
          <util:list list-class="java.util.concurrent.CopyOnWriteArrayList">
              <ref bean="LoggingInInterceptor"/>
          </util:list>
      </property>
      <property name="outInterceptors">
          <util:list list-class="java.util.concurrent.CopyOnWriteArrayList">
              <ref bean="LoggingOutInterceptor"/>
          </util:list>
      </property>
      <property name="inFaultInterceptors">
          <util:list list-class="java.util.concurrent.CopyOnWriteArrayList">
              <ref bean="LoggingInInterceptor"/>
          </util:list>
      </property>
      <property name="outFaultInterceptors">
          <util:list list-class="java.util.concurrent.CopyOnWriteArrayList">
              <ref bean="LoggingOutInterceptor"/>
          </util:list>
      </property>
      

      This is probably overkill since the setter methods could probably handle
      this by adding the list to the existing CopyOnWriteArrayList rather than
      overwriting the existing object, for example:

          /**
              * Specifies a list of interceptors used to process requests recieved
              * by the endpoint.
              *
              * @param interceptors   a list of <code>Interceptor</code> objects
              * @org.apache.xbean.Property description="a list of beans configuring interceptors that process incoming requests"
              * */
          public void setInInterceptors(List<Interceptor> interceptors) {
              in.addAll(interceptors);
          }
      

      This would allow current configurations to avoid possible ConcurrentModificationExceptions

      Attachments

        Activity

          People

            ffang Freeman Yue Fang
            martinmurphy Martin Murphy
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: