3 Replies Latest reply on Apr 19, 2009 1:20 PM by derkd

    java.util.ConcurrentModificationException

    derkd
      Hi,

      I'm getting an java.util.ConcurrentModificationException when pressing a commandButton which invokes a method on my webservice client with Internet Explorer. I don't get this with firefox.
      Can someone helps me with this issue or direct me in the right way?

      I use Seam 1.2.1 and richfaces 3.1.6

      ...
      <h:inputText id="zoekBeroep" value="#{zoekBeroepAction.zoekterm}" style="width : 350px;"/>
                     <h:commandButton value="Zoek" action="#{zoekBeroepAction.findBeroepLetterCombinatie}" eventsQueue="ZoekBeroep" ignoreDupResponses="true"/>
                     
                      <rich:dataList var="_beroep" value="#{beroepen}">
                           <h:outputLink id="beroep" onclick="registreer('#{_beroep.cdBeroepsnaam}+#{_beroep.omsBeroepsnaam}')">#{_beroep.omsBeroepsnaam}</h:outputLink>
                           <h:outputText value="   " />
                          <h:outputLink value="#" id="link" >
                            <h:graphicImage id="information" style="border-width:0" value="../images/I.png" />
                            <rich:componentControl for="informationPanel" attachTo="link" operation="show" event="onclick"/>
                          </h:outputLink>
                     </rich:dataList>
      ...


      the method to invoke:

      ...
           public String findBeroepLetterCombinatie(){
                beroepen = null;
                log.debug("Lettercombinatie: trying to invoke findBeroep on BOCwebservice...");
                beroepen = beroepAdapter.findBeroep(zoekterm, 1);     
                if(beroepen != null){
                     log.debug("beroepen != null");
                }else{
                     log.debug("beroepen == null");
                }
                return "retrievedFindBeroepLettercombinatie";
           }
      ...

      Web.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
           version="2.4">

           <!-- Seam -->

           <listener>
                <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
           </listener>
           
           <servlet>
                <servlet-name>Faces Servlet</servlet-name>
                <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
                <load-on-startup>1</load-on-startup>
           </servlet>
           <!-- Faces Servlet Mapping -->
           <servlet-mapping>
                <servlet-name>Faces Servlet</servlet-name>
                <url-pattern>*.seam</url-pattern>
           </servlet-mapping>

           <servlet-mapping>
                <servlet-name>Seam Remoting</servlet-name>
                <url-pattern>/seam/remoting/*</url-pattern>
           </servlet-mapping>
           
           <servlet>
              <servlet-name>Seam Resource Servlet</servlet-name>
              <servlet-class>org.jboss.seam.servlet.ResourceServlet</servlet-class>
          </servlet>
         
          <servlet-mapping>
              <servlet-name>Seam Resource Servlet</servlet-name>
              <url-pattern>/seam/resource/*</url-pattern>
          </servlet-mapping>
           
           <!-- Propagate conversations across redirects -->
           <!-- <filter>
                <filter-name>Seam Redirect Filter</filter-name>
                <filter-class>org.jboss.seam.servlet.SeamRedirectFilter</filter-class>
           </filter>

           <filter-mapping>
                <filter-name>Seam Redirect Filter</filter-name>
                <url-pattern>*.seam</url-pattern>
           </filter-mapping>-->

           <!-- MyFaces -->

           <!-- <listener>
                <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
           </listener>-->

           <context-param>
                <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
                <param-value>client</param-value>
           </context-param>

           <!-- <context-param>
                <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
                <param-value>.jspx</param-value>
           </context-param>-->
           <context-param>
              <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
              <param-value>.xhtml</param-value>
          </context-param>

           

           <servlet>
                <servlet-name>Seam Remoting</servlet-name>
                <servlet-class>org.jboss.seam.remoting.SeamRemotingServlet</servlet-class>
                <load-on-startup>2</load-on-startup>
           </servlet>

      <!-- <listener>
         <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
      </listener>-->
      <!-- Plugging the "Blue Sky" skin into the project -->
      <context-param>
         <param-name>org.richfaces.SKIN</param-name>
         <param-value>blueSky</param-value>
      </context-param>

      <!-- Making the RichFaces skin spread to standard HTML controls -->
      <context-param>
            <param-name>org.richfaces.CONTROL_SKINNING</param-name>
            <param-value>enable</param-value>
      </context-param>

      <!-- Defining and mapping the RichFaces filter -->
      <filter>
         <display-name>RichFaces Filter</display-name>
         <filter-name>richfaces</filter-name>
         <filter-class>org.ajax4jsf.Filter</filter-class>
      </filter>

      <context-param>
           <param-name>org.ajax4jsf.SERIALIZE_SERVER_STATE</param-name>
           <param-value>true</param-value>
      </context-param>
      <context-param>
           <param-name>com.sun.faces.serializeServerState</param-name>
           <param-value>true</param-value>
      </context-param>

      <filter-mapping>
         <filter-name>richfaces</filter-name>
         <servlet-name>Faces Servlet</servlet-name>
         <dispatcher>REQUEST</dispatcher>
         <dispatcher>FORWARD</dispatcher>
         <dispatcher>INCLUDE</dispatcher>
      </filter-mapping>

      <security-constraint>
              <display-name>Restrict raw XHTML Documents</display-name>
              <web-resource-collection>
                  <web-resource-name>XHTML</web-resource-name>
                  <url-pattern>*.xhtml</url-pattern>
              </web-resource-collection>
              <auth-constraint/>
          </security-constraint>
         
          <welcome-file-list>
              <welcome-file>index.html</welcome-file>
          </welcome-file-list>

      </web-app>

      Error:

      SEVERE: Error Rendering View[/beroepen/lettercombinatie.xhtml]
      java.util.ConcurrentModificationException
              at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)
              at java.util.HashMap$KeyIterator.next(HashMap.java:877)
              at java.util.Collections$1.nextElement(Collections.java:3383)
              at com.sun.faces.context.RequestMap.entrySet(ExternalContextImpl.java:66
      6)
              at java.util.AbstractMap.containsKey(AbstractMap.java:136)
              at com.sun.facelets.FaceletViewHandler.getResponseContentType(FaceletVie
      wHandler.java:461)
              at com.sun.facelets.FaceletViewHandler.createResponseWriter(FaceletViewH
      andler.java:383)
              at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.jav
      a:550)
              at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWra
      pper.java:108)
              at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.j
      ava:216)
              at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePha
      se.java:107)
              at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
              at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
              at com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterC
      hain.java:64)
              at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)

              at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
              at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletReque
      stDispatcher.java:623)
              at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(Ser
      vletRequestDispatcher.java:370)
              at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequ
      estHandler.java:871)
              at com.evermind.server.http.HttpRequestHandler.processRequest(HttpReques
      tHandler.java:453)
              at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpReque
      stHandler.java:221)
              at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.ja
      va:122)
              at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.ja
      va:111)
              at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSo
      cketReadHandler.java:260)
              at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(Relea
      sableResourcePooledExecutor.java:303)
              at java.lang.Thread.run(Thread.java:595)
        • 1. Re: java.util.ConcurrentModificationException
          derkd

          After further testing I also get this with firefox. I don't know what I'm doing wrong. I removed all the calls to the webservice by commenting it out.


          so my simple code looks like this now:


          my page:


          <ui:define name="body">
                  <script src="js/beroep.js" type="text/javascript"></script>
              <h:form>    
                  <h:panelGrid columns="2" width="100%">
                                  <h:inputText id="zoekBeroep" value="#{zoekBeroepAction.zoekterm}" style="width : 350px;"/>
                                  <h:commandButton value="Zoek" action="#{zoekBeroepAction.findBeroepLetterCombinatie}"/>
                                   
                                  <rich:dataList id="lettercombinatieList" var="_beroep" value="#{zoekBeroepAction.beroepen}">
                                          <h:outputLink id="beroep" onclick="registreer('#{_beroep.cdBeroepsnaam}+#{_beroep.omsBeroepsnaam}')">#{_beroep.omsBeroepsnaam}</h:outputLink>
                                          <h:outputText value="   " />
                                          <h:outputLink value="#" id="link" >
                                            <h:graphicImage id="information" style="border-width:0" value="../images/I.png" />
                                            <rich:componentControl for="informationPanel" attachTo="link" operation="show" event="onclick"/>
                                          </h:outputLink>
                                  </rich:dataList>
                                  
                                   <rich:modalPanel id="informationPanel" width="800" height="500">
                                  <f:facet name="header">
                                      <h:panelGroup>
                                          <h:outputText value="#{selectedBeroep.omsBeroepsnaam}"></h:outputText>
                                      </h:panelGroup>
                                  </f:facet>
                                  <f:facet name="controls">
                                      <h:panelGroup>
                                          <h:graphicImage value="../images/close.png" styleClass="hidelink" id="hidelink"/>
                                          <rich:componentControl for="informationPanel" attachTo="hidelink" operation="hide" event="onclick"/>
                                      </h:panelGroup>
                                  </f:facet>
                          </rich:modalPanel>        
                  </h:panelGrid>
              </h:form>
                  </ui:define>
          </ui:composition>




          ZoekBeroepAction:


          @Name("zoekBeroepAction")
          @Scope(ScopeType.CONVERSATION)
          public class ZoekBeroepAction {
                  
                  @Logger private Log log;
                  
                  private String zoekterm;
                  @In(create = true) private BeroepAdapter beroepAdapter;
                  
          //      @DataModel(scope = ScopeType.PAGE)
                  protected List<IBeroep> beroepen;
                  
          //      @DataModelSelection
          //      @Out(required = false) 
          //      protected IBeroep selectedBeroep;
          
                  public ZoekBeroepAction(){
                          super();
                  }
          
                  public String getZoekterm() {
                          return zoekterm;
                  }
          
                  public void setZoekterm(String zoekterm) {
                          this.zoekterm = zoekterm;
                  }
                  
                  public List<IBeroep> getBeroepen() {
                          return beroepen;
                  }
          
                  public void setBeroepen(List<IBeroep> beroepen) {
                          this.beroepen = beroepen;
                  }
          
                  public void findBeroepLetterCombinatie(){
          //              beroepen = null;
                          log.debug("Lettercombinatie: trying to invoke findBeroep on BOCwebservice...");
          //              beroepen = beroepAdapter.findBeroep(zoekterm, 1);       
                          if(beroepen != null){
                                  log.debug("beroepen != null");
                          }else{
                                  log.debug("beroepen == null");
                          }
                  }
          }




          Can somebody please help me with this one???

          • 2. Re: java.util.ConcurrentModificationException
            derkd

            Ok I'm a bit further again. I managed to isolate the problem. It goes wrong with the injection of my beroepAdapter:


             @In(create = true) private BeroepAdapter beroepAdapter;



            I don't know why because I do not make a call to it.


            mij beroepAdapter looks like this:



            package org.uwv.boc.web.app.webservice;
            
            import java.util.Iterator;
            import java.util.LinkedList;
            import java.util.List;
            
            import org.jboss.seam.annotations.In;
            import org.jboss.seam.annotations.Logger;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.log.Log;
            import org.uwv.boc.web.app.IBeroep;
            import org.uwv.boc.web.app.IBeroepSector;
            import org.uwv.boc.web.app.impl.BeroepImpl;
            import org.uwv.boc.web.app.impl.BeroepSectorImpl;
            import org.uwv.boc.web.service.BeroepSector;
            import org.uwv.boc.web.service.BeroepsnaamGecodeerd;
            import org.uwv.boc.web.service.SbcBeroepNiveau;
            import org.uwv.boc.web.service.ZoektermsArray;
            
            @Name("beroepAdapter")
            public class BeroepAdapter {
                 
                 @In(create = true) private BOCWebservice bocWebservice;
                 @Logger Log log;
                 
                 public List<IBeroepSector> getAllBeroepSector(){
                      List<IBeroepSector> iBeroepSector = null;
                      List<BeroepSector> beroepSector = bocWebservice.getBOC().getAllBeroepSector();
                      iBeroepSector = convertBeroepSector(beroepSector);
                      
                      return iBeroepSector;
                 }
                 
                 public List<SbcBeroepNiveau> getAllSbcBeroepGroep(){
                      List<SbcBeroepNiveau> beroepNiveau = null;
                      
                      beroepNiveau = bocWebservice.getBOC().getAllSbcBeroepGroep();
                      
                      return beroepNiveau;
                 }
                 
                 public List<IBeroep> findBeroep(String zoektermString, int indTrigramZoeken){
                      List<IBeroep> beroepen = null;
                      
                      ZoektermsArray zoekterms = new ZoektermsArray();
                      zoekterms.getZoekterm().add(zoektermString);
                      List<BeroepsnaamGecodeerd> beroepsnaamGecodeerd = bocWebservice.getBOC().findBeroep(zoekterms, indTrigramZoeken, null, null, null, null, null, 50);
                      beroepen = convertBeroepsnaamGecodeerd(beroepsnaamGecodeerd);
                      return beroepen;
                 }
                 
                 public List<IBeroep> getBeroepRelaties(Long cdBeroepsnaam){
                      List<IBeroep> beroepen = null;
                      
                      List<BeroepsnaamGecodeerd> beroepsnaamGecodeerd = bocWebservice.getBOC().getBeroepRelaties(cdBeroepsnaam);
                      beroepen = convertBeroepsnaamGecodeerd(beroepsnaamGecodeerd);
                      return beroepen;
                 }
                 
                 public List<IBeroep> convertBeroepsnaamGecodeerd(List<BeroepsnaamGecodeerd> beroepsnaamGecodeerd){
                      List<IBeroep> beroepen = new LinkedList<IBeroep>();
                      log.debug("trying to convert List<BeroepsnaamGecodeerd>");
                      Iterator<BeroepsnaamGecodeerd> iter = beroepsnaamGecodeerd.iterator();
                      
                      while(iter.hasNext()){
                           BeroepsnaamGecodeerd beroepsnaamGecod = iter.next();
                           IBeroep iBeroep = new BeroepImpl();
                           log.debug("beroepsnaamGecod.getOmsBeroepsnaam(): " + beroepsnaamGecod.getOmsBeroepsnaam());
                           
                           iBeroep.setCdBeroepsnaam(beroepsnaamGecod.getCdBeroepsnaam());
                           iBeroep.setAantGedragscompetentie(beroepsnaamGecod.getAantGedragscompetentie());
                           iBeroep.setArbeidsomstandigheden(beroepsnaamGecod.getArbeidsomstandigheden());
                           iBeroep.setBeroepNiveau(beroepsnaamGecod.getBeroepNiveau());
                           iBeroep.setBeroepSector(beroepsnaamGecod.getBeroepSector());
                           iBeroep.setBeroepVerwantschap(beroepsnaamGecod.getBeroepVerwantschap());
                           iBeroep.setCapaciteiten(beroepsnaamGecod.getCapaciteiten());
                           iBeroep.setCdSrtBeroepsnaam(beroepsnaamGecod.getCdSrtBeroepsnaam());
                           iBeroep.setGedragscompetentie(beroepsnaamGecod.getGedragscompetentie());
                           iBeroep.setIndBeroepsnaamActief(beroepsnaamGecod.getIndBeroepsnaamActief());
                           iBeroep.setIndBeroepsnaamActueel(beroepsnaamGecod.getIndBeroepsnaamActueel());
                           iBeroep.setIndOvereenkomstReferentieberoep(beroepsnaamGecod.getIndOvereenkomstReferentieberoep());
                           iBeroep.setKorteSchets(beroepsnaamGecod.getKorteSchets());
                           iBeroep.setOpleidingseisen(beroepsnaamGecod.getOpleidingseisen());
                           iBeroep.setOpleidingsnaamGecodeerd(beroepsnaamGecod.getOpleidingsnaamGecodeerd());
                           iBeroep.setOmsBeroepsnaam(beroepsnaamGecod.getOmsBeroepsnaam());
                           iBeroep.setPercOvereenkomstZoekterm(beroepsnaamGecod.getPercOvereenkomstZoekterm());
                           iBeroep.setSalarisperspectief(beroepsnaamGecod.getSalarisperspectief());
                           iBeroep.setToelBeroepencluster(beroepsnaamGecod.getToelBeroepencluster());
                           iBeroep.setWerkomgeving(beroepsnaamGecod.getWerkomgeving());
                           iBeroep.setWerkzaamheden(beroepsnaamGecod.getWerkzaamheden());
                      
                           if(beroepsnaamGecod.getBeroepsnaamGecodeerd() != null && beroepsnaamGecod.getBeroepsnaamGecodeerd().size() > 0){
                                log.debug("beroepsnaamGecod.getBeroepsnaamGecodeerd() != null");
                                iBeroep.setBeroepsnaamGecodeerd(convertBeroepsnaamGecodeerd(beroepsnaamGecod.getBeroepsnaamGecodeerd()));
                           }
                           log.debug("add beroep to beroepen...");
                           beroepen.add(iBeroep);
                      }
                      
                      return beroepen;
                 }
                 
                 public List<IBeroepSector> convertBeroepSector(List<BeroepSector> beroepSectorenWS){
                      List<IBeroepSector> beroepSectoren = new LinkedList<IBeroepSector>();
                      log.debug("trying to convert List<BeroepSector>");
                      Iterator<BeroepSector> iter = beroepSectorenWS.iterator();
                      
                      while(iter.hasNext()){
                           BeroepSector beroepSector = iter.next();
                           IBeroepSector iBeroepSector = new BeroepSectorImpl();
                           log.debug("beroepSector.getOmsSector(): " + beroepSector.getOmsSector());
                           
                           iBeroepSector.setCdSector(beroepSector.getCdSector());
                           iBeroepSector.setIndSectorActief(beroepSector.getIndSectorActief());
                           iBeroepSector.setOmsSector(beroepSector.getOmsSector());
            
                           if(beroepSector.getBeroepSector() != null && beroepSector.getBeroepSector().size() > 0){
                                log.debug("beroepSectorWS.getBeroepSector() != null");
                                iBeroepSector.setType("beroepSectorGroep");
                                iBeroepSector.setBeroepSector(convertBeroepSector(beroepSector.getBeroepSector()));
                           }else{
                                iBeroepSector.setType("beroepSector");
                                iBeroepSector.setBeroepSector(null);
                           }
                           log.debug("add beroepSector to beroepSectoren...");
                           beroepSectoren.add(iBeroepSector);
                      }
                      
                      return beroepSectoren;
                 }
            
            }



            Can it have something to do with scopes? I use the beroepAdapter to convert data retrieved from the webservice client code into my own objects...


            Any ideas?

            • 3. Re: java.util.ConcurrentModificationException
              derkd

              The problem seems to be solved by setting the beroepAdapter to session scope.


              I still don't see why this is the solution. As far as I know when you don't set a scope the default scope is converstation scope. So when I load the page it injects the beroepAdapter in my ZoekBeroepAction:


              (@In(create = true) private BeroepAdapter beroepAdapter;



              this means that if the beroepadapter is not yet created then it should create a new object, right?


              now when I click on the button it invokes a method and gives me an concurrentModificationException (even without using the beroepAdapter in the particulair method). Now when I set the beroepAdapter to session scope everything works as expected.


              Why doesn't this work when I set this to converstation scope???