title: Duplicate id when dynamically adding new component to JSF component tree
body: <p>Using JSF 2.1, Mojarra 2.1.3, Glassfish 3.1.1, and PrimeFaces 3.3.1</p>
  
  <p>I'm trying to handle processing field level security in JSF, on the preRenderView event, and having issues when needing to add a dynamic component to the JSF component tree. On first render, everything is fine and field level security is processed. After any sort of update, however, Mojarra complains about a duplicate id even though, through printing to the console, my add code is only running once per update.</p>
  
  <p>It appears as if Mojarra isn't clearing the component tree for postbacks and thus each subsequent rendered update adds an additional version of the component to the tree.</p>
  
  <p>Thanks for any help anyone can provide. Here's some dumbed-down sample code. On commandButton click the error is thrown.</p>
  
  <p>index.xhtml:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:p="http://primefaces.org/ui"
          &gt;
      &lt;f:event listener="#{lifeCycle.event}" type="preRenderView" /&gt;
      &lt;h:body&gt;
          &lt;h:form id="form" prependId="false"&gt;
              &lt;h:panelGroup id="testPanel"&gt;
                  &lt;h:inputText id="viewSec" value="viewSec node"/&gt;&lt;br/&gt;
              &lt;/h:panelGroup&gt;
              &lt;p:commandButton update="testPanel"/&gt;
          &lt;/h:form&gt;
      &lt;/h:body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>LifeCycle.java:</p>
  
  <pre><code>package com.dynamic.test;
  
  import java.io.Serializable;
  import java.util.List;
  import javax.faces.bean.ManagedBean;
  import javax.faces.bean.RequestScoped;
  import javax.faces.component.UIComponent;
  import javax.faces.component.UIViewRoot;
  import javax.faces.component.html.HtmlOutputText;
  import javax.faces.component.visit.VisitContext;
  import javax.faces.context.FacesContext;
  import javax.faces.event.ComponentSystemEvent;
  
  @ManagedBean
  @RequestScoped
  public class LifeCycle implements Serializable {
      public void event(ComponentSystemEvent event){
          FacesContext facesContext = FacesContext.getCurrentInstance();
          UIViewRoot root = facesContext.getViewRoot();
          NodeInspector visitCallback = new NodeInspector();
  
          root.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), visitCallback);
  
          List&lt;UIComponent&gt; securityEnabledComponents = visitCallback.getSecurityEnabledComponents();
          for (UIComponent securityEnabledComponent : securityEnabledComponents) {
  
              if(securityEnabledComponent.getClientId().equals("viewSec")){
                  List&lt;UIComponent&gt; childList = securityEnabledComponent.getParent().getChildren();
                  int targetPosition = securityEnabledComponent.getParent().getChildren().indexOf(securityEnabledComponent);
  
                  HtmlOutputText outputTextComponent = new HtmlOutputText();
                  outputTextComponent.setId(securityEnabledComponent.getId());
                  outputTextComponent.setValue(securityEnabledComponent.getAttributes().get("value"));
  
                  childList.set(targetPosition, outputTextComponent);
              }
          }
      }
  }
  </code></pre>
  
  <p>NodeInspector.java</p>
  
  <pre><code>package com.dynamic.test;
  
  import java.util.ArrayList;
  import java.util.List;
  import javax.faces.component.UIComponent;
  import javax.faces.component.visit.VisitCallback;
  import javax.faces.component.visit.VisitContext;
  import javax.faces.component.visit.VisitResult;
  import javax.faces.context.FacesContext;
  
  public class NodeInspector implements VisitCallback {
      private List&lt;UIComponent&gt; securityEnabledComponents = new ArrayList&lt;UIComponent&gt;();
      FacesContext facesContext = FacesContext.getCurrentInstance();
  
      @Override
      public VisitResult visit(final VisitContext context, final UIComponent target) {
          if(target.getClientId().equals("viewSec")){
              securityEnabledComponents.add(target);
          }
          return VisitResult.ACCEPT;
      }
  
      public List&lt;UIComponent&gt; getSecurityEnabledComponents() {
          return securityEnabledComponents;
      }
  }
  </code></pre>
  
  <p>Error:</p>
  
  <pre><code>SEVERE: JSF1007: Duplicate component ID viewSec found in view.
      ...  +id: j_idt2
         type: &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  
        +id: j_idt3
         type: javax.faces.component.UIOutput@17098e7
          +id: form
           type: javax.faces.component.html.HtmlForm@14677de
            +id: testPanel
             type: javax.faces.component.html.HtmlPanelGroup@167ab25
              +id: viewSec  &lt;===============
               type: javax.faces.component.html.HtmlOutputText@14a3d2e
              +id: viewSec  &lt;===============
               type: javax.faces.component.html.HtmlOutputText@f6a607
              +id: j_idt4
               type: &lt;br/&gt;
  
            +id: j_idt5
             type: org.primefaces.component.commandbutton.CommandButton@1380fc5
        +id: j_idt6
         type: 
      &lt;/html&gt;...
  
      SEVERE: Error Rendering View[/index.xhtml]
      java.lang.IllegalStateException: Component ID viewSec has already been found in the view.  
          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)...
  </code></pre>