title: JSF: When to add ClientBehavior to own component
body: <p>I am developing a component containing an AJAX client behavior. The behavior depends on the parameters provided to the component (e.g. render and execute targets). Due to performance reasons I do not want to realize the component using facelet based composite components.</p>
  
  <p>My question is, when the client behavior shall be added to the component. If I call <code>addClientBehavior()</code> in the <code>encodeBegin()</code> method, I receive a <code>NullPointerException</code> in <code>UIComponentBase.restoreBehaviorsState()</code>. If I add the behavior at construction time, the ajax request works, however the parameters are not yet available. Is there a suitable method or event when to properly add the behavior?</p>
  
  <p>I use mojarra 2.1.7. Below is a short example of my component without the dynamic ajax stuff:</p>
  
  <pre><code>@FacesComponent(value="simpleTestLink")
  public class SimpleTestLink extends HtmlCommandLink{
  
  
      private Logger logger=LoggerFactory.getLogger(getClass());
      private AjaxBehavior ajax;
  
      enum PropertyKeys{aProp};
  
      public SimpleTestLink() {
          logger.debug("SimpleTestLink created");
          // adding ajax here works, but no parameters available yet
          ajax = new AjaxBehavior();
          ajax.setExecute(Arrays.asList(new String[]{"@this"}));
          ajax.setRender(Arrays.asList(new String[]{"@form"}));
          addClientBehavior(getDefaultEventName(), ajax);
  
      }
  
      @Override
      public void encodeBegin(FacesContext context) throws IOException {
          logger.debug("encodeBegin num: " + getAttr());
          // adding ajax here fails
          super.encodeBegin(context);
      }
  
      @Override
      public boolean getRendersChildren() {
          return true;
      }
  
      @Override
      public void encodeChildren(FacesContext context) throws IOException {
          Object attr = getAttr();
          HtmlOutputText outputText = new HtmlOutputText();
          outputText.setValue("testlink["+ attr+"]\n");
          outputText.encodeAll(context);
          super.encodeChildren(context);
      }
  
      private Object getAttr() {
          return getAttributes().get(PropertyKeys.aProp.name());
      }
  
  }
  </code></pre>
  
  <p>Thanks for any help,<br/>
  Jens</p>