title: JSF MethodExpression isn't triggering my backing bean action
body: <p>I have the problem that my code isn't triggering the action in my backing bean. The code is as follows:</p>
  
  <pre><code>HtmlCommandButton replyCommentButton = new HtmlCommandButton();
  replyCommentButton.setId("replyCommentButton" + commentCounter);
  replyCommentButton.setValue("Create reply");
  String action = "#{Handler.action_replyToComment}";
  MethodExpression methodExpression =  
  FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
  createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
  new Class&lt;?&gt;[0]);
  replyCommentButton.setActionExpression(methodExpression);
  </code></pre>
  
  <p>In my backing bean called RequestHandlerBean, defined in FacesConfig as Handler, I have the following code:</p>
  
  <pre><code>public void action_replyToComment() {
  logger.info("Homemade action called!!!");
  System.out.println("Homemade action called!!!");
  }
  </code></pre>
  
  <p>Does anyone spot why nothing happens when I click the button? It isn't triggering the event properly. The source of the html code is as follows:</p>
  
  <pre><code>&lt;input id="replyCommentButton1" type="submit" value="Create reply"   
  name="replyCommentButton1"/&gt;
  </code></pre>
  
  <p>As we can see there's no action defined in the HTML. </p>
  
  <p><strong>Edit 2:</strong> I just found out in Javadoc that my action method has to be a public String. I've changed this in my backing bean now so the code in my backing bean is:</p>
  
  <pre><code>public String action_replyToComment() {
  logger.info("Homemade action called!!!");
  System.out.println("Homemade action called!!!");
  return null;
  }
  </code></pre>
  
  <hr>
  
  <p>Edit2: I've also made sure that I have it encapsulated within a  tag, but still no luck. Shouldn't there be a action attribute on the  element?</p>
  
  <hr>
  
  <p><strong>Edit3: My bean is defined in my faces-config like this:</strong></p>
  
  <pre><code>&lt;managed-bean&gt;
  &lt;description&gt;
  Handles the specific request.
  &lt;/description&gt;
  &lt;managed-bean-name&gt;Handler&lt;/managed-bean-name&gt;
  &lt;managed-bean-class&gt;no.ngt.tech.rt2.beans.RequestHandlerBean&lt;/managed-bean-class&gt;
  &lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;
  &lt;/managed-bean&gt;
  </code></pre>
  
  <p>Also if I choose to output in my JSF page like this: </p>
  
  <pre><code>&lt;a4j:commandButton action="#{Handler.action_replyToComment}" value="Reply" /&gt; 
  </code></pre>
  
  <p>That works perfectly</p>
  
  <p><strong>EDIT 4 - MY JSP PAGE</strong>
  Note Ive also tried using the depreciated setAction(methodBinding) now too, but sadly it didnt work either. </p>
  
  <pre><code>&lt;%@ include file="_includes.jsp" %&gt;
  &lt;f:view&gt;
  &lt;html&gt;
  &lt;head&gt;
  &lt;title&gt;&lt;h:outputText value="#{msgs.title}" /&gt;&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
  
  
  
  &lt;%@ include file="_menu.jsp" %&gt;
  
  &lt;rich:tabPanel switchType="client"&gt;
  
  &lt;rich:tab id="commentsTab" label="Comments" rendered="#{Handler.editRequest}"&gt;
  &lt;h:form&gt;
           &lt;ngt:commentTree binding="#{Handler.commentTree}" value="#{Handler.comments}"  /&gt;
  
           &lt;br /&gt;
  
           &lt;a4j:commandButton action="#{Handler.action_replyToComment}" value="testbutton" /&gt;
  &lt;/h:form&gt;    
  &lt;/rich:tab&gt;
  
  
  &lt;/rich:tabPanel&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  &lt;/f:view&gt;
  </code></pre>
  
  <p><strong>menu.jsp:</strong></p>
  
  <pre><code>&lt;h:form&gt;
      &lt;rich:toolBar itemSeparator="line" styleClass="toolbar" contentClass="toolbar" height="22"&gt;
          &lt;rich:toolBarGroup&gt;
              &lt;rich:menuItem submitMode="server" value="Front" action="#{newRT.action_showFront}" /&gt;
          &lt;/rich:toolBarGroup&gt;
          &lt;rich:toolBarGroup&gt;
              &lt;rich:menuItem submitMode="server" value="New request" action="#{Step.action_showSteps}" /&gt;
          &lt;/rich:toolBarGroup&gt;
          &lt;rich:toolBarGroup&gt;
              &lt;rich:menuItem submitMode="server" value="Requests" action="#{Handler.action_showRequestsView}" /&gt;
          &lt;/rich:toolBarGroup&gt;
          &lt;rich:toolBarGroup&gt;
              &lt;rich:menuItem submitMode="server" value="Control-panel" action="#" /&gt;
          &lt;/rich:toolBarGroup&gt;
          &lt;rich:toolBarGroup location="right"&gt;
              &lt;h:inputText styleClass="barsearch" value="#{Handler.search}" /&gt;
              &lt;a4j:commandButton styleClass="barsearchbutton" action="#{Handler.action_GetRequestFromID}"  value="Search" /&gt;
          &lt;/rich:toolBarGroup&gt;
      &lt;/rich:toolBar&gt;
  &lt;/h:form&gt;
  
  
  &lt;br/&gt;&lt;br/&gt;
  </code></pre>
  
  <p><strong>Includes.jsp</strong></p>
  
  <pre><code>&lt;%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %&gt;
  &lt;%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %&gt;
  &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt;
  &lt;%@ taglib prefix="a4j" uri="http://richfaces.org/a4j" %&gt;
  &lt;%@ taglib prefix="rich" uri="http://richfaces.org/rich"%&gt;
  &lt;%@ taglib prefix="ngt" uri="http://MySpecialTagLib.no/"%&gt;
  </code></pre>
  
  <p><strong>Edit 7 - Java code for UIComponent:</strong></p>
  
  <p>This is CommentsTreeUI.java:</p>
  
  <pre><code>public class CommentsTreeUI extends UIOutput {
  
      private static Logger logger = Logger.getLogger(CommentsTreeUI.class.getName());
  
      @Override
      public void encodeBegin(FacesContext context) throws IOException {
  
          List&lt;CommentTag&gt; value = (List&lt;CommentTag&gt;) getAttributes().get("value");
          int commentCounter = 0;
  
          if (value != null) {
              for (CommentTag comment : value) {
                  commentCounter++;
                  ResponseWriter commentContainerWriter = context.getResponseWriter();
                  commentContainerWriter.startElement("div", this);
                  commentContainerWriter.writeAttribute("id", "Comment" + commentCounter, null);
  
                  String width = comment.getWidth();
                  String height = comment.getHeight();
  
                  String style = comment.getStyle();
  
                  style = (style != null) ? style + ";" : "";
  
                  if (width != null) {
                      style += "width:" + width + ";";
                  }
                  if (height != null) {
                      style += "height:" + height + ";";
                  }
  
                  commentContainerWriter.writeAttribute("style", style, null);
  
                  String newComment = comment.getNewComment();
                  if (newComment == null) {
                      newComment = "false";
                  }
  
                  String level = comment.getLevel();
  
                  if (level != null) {
                      level = "commentContainerLevel" + level + newComment;
                  }
                  commentContainerWriter.writeAttribute("class", level, null);
  
                  String title = comment.getTitle();
                  if (title != null) {
                      commentContainerWriter.writeAttribute("title", title, null);
                  }
  
                  String titleText = comment.getTitleText();
                  if (titleText != null) {
                      ResponseWriter titleTextWriter = context.getResponseWriter();
                      UIOutput titleTextComponent = new UIOutput();
                      titleTextWriter.startElement("div", titleTextComponent);
                      titleTextWriter.writeAttribute("class", "commentHeaderText" + newComment, null);
                      titleTextWriter.writeText(titleText + " | ", null);
                      titleTextWriter.startElement("a", titleTextComponent);
                      titleTextWriter.writeAttribute("onclick", "showCommentReply('CommentReply" + commentCounter + "')", null);
                      titleTextWriter.writeAttribute("class", "reply", null);
                      titleTextWriter.writeText("Reply", null);
                      titleTextWriter.endElement("a"); 
                      titleTextWriter.endElement("div");
                  }
  
                  String commentBody = comment.getCommentBody();
                  if (commentBody != null) {
                      ResponseWriter commentBodyWriter = context.getResponseWriter();
                      UIOutput commentBodyComponent = new UIOutput();
                      commentBodyWriter.startElement("div", commentBodyComponent);
                      commentBodyWriter.writeText(commentBody, null);
                      commentBodyWriter.endElement("div");
                  }
  
                  ResponseWriter replyContainerWriter = context.getResponseWriter();
                  UIOutput replyContainerComponent = new UIOutput();
                  replyContainerWriter.startElement("div", replyContainerComponent);
                  commentContainerWriter.writeAttribute("id", "CommentReply" + commentCounter, null);
                  replyContainerWriter.writeAttribute("class", "replyContainer", null);
  
                  ResponseWriter replyHeaderWriter = context.getResponseWriter();
                  UIOutput replyHeaderComponent = new UIOutput();
                  replyHeaderWriter.startElement("div", replyHeaderComponent);
                  replyHeaderWriter.writeAttribute("class", "replyHeaderContainer", null);
                  replyHeaderWriter.endElement("div");
  
                  ResponseWriter replyFormWriter = context.getResponseWriter();
                  UIInput replyFormComponent = new UIInput();
                  replyFormWriter.startElement("fieldset", replyFormComponent);
                  replyFormWriter.startElement("textarea", replyFormComponent);
                  replyFormWriter.writeAttribute("type", "textarea", null);
                  replyFormWriter.writeAttribute("rows", "5", null);
                  replyFormWriter.writeAttribute("cols", "76", null);
                  replyFormWriter.writeText("Write your answer here", null);
                  replyFormWriter.endElement("textarea");
  
  
                  //TODO: Fix so button has action to backing bean
                  HtmlAjaxCommandButton replyCommentButton = new HtmlAjaxCommandButton();
                  replyCommentButton.setId("replyCommentButton" + commentCounter);
                  replyCommentButton.setValue("Create reply");
                  String action = "#{RequestHandlerBean.action_replyToComment}";
                  //replyCommentButton.setReRender("commentsTree");
                  ExpressionFactory factory = context.getApplication().getExpressionFactory();
                  Class [] argtypes=new Class[1];
                  argtypes[0]=ActionEvent.class;
  
                  MethodExpression replyActionExpression = factory.createMethodExpression(context.getELContext(), action, null, argtypes);
                  replyCommentButton.setActionExpression(replyActionExpression);
  
                  MethodExpression methodExpression = context.getCurrentInstance().getApplication().getExpressionFactory().
                          createMethodExpression(context.getCurrentInstance().getELContext(), action, null, new Class&lt;?&gt;[0]);
                  replyCommentButton.setActionExpression(methodExpression);
                  /*
                  replyCommentButton.setAction(context.getApplication().createMethodBinding(action, argtypes));
                  */
  
                  replyCommentButton.encodeAll(context);
                  //Todo above
  
  
                  replyFormWriter.writeText(" ", null);
                  replyFormWriter.startElement("input", replyFormComponent);
                  replyFormWriter.writeAttribute("type", "button", null);
                  replyFormWriter.writeAttribute("value", "Cancel ", null);
                  replyFormWriter.writeAttribute("onclick", "hideCommentReply('CommentReply" + commentCounter + "')", title);
                  replyFormWriter.endElement("input");
                  replyFormWriter.endElement("fieldset");
                  replyContainerWriter.endElement("div");
                  commentContainerWriter.endElement("div");
              }
          } else { //value==null
              ResponseWriter writer = context.getResponseWriter();
              writer.startElement("div", this);
  
              writer.writeAttribute("id", getClientId(context), null);
  
              String width = (String) getAttributes().get("width");
              String height = (String) getAttributes().get("height");
  
              String style = (String) getAttributes().get("style");
  
              style = (style != null) ? style + ";" : "";
  
              if (width != null) {
                  style += "width:" + width + ";";
              }
              if (height != null) {
                  style += "height:" + height + ";";
              }
  
              writer.writeAttribute("style", style, null);
  
              String styleClass = (String) getAttributes().get("styleClass");
              if (styleClass != null) {
                  writer.writeAttribute("class", styleClass, null);
              }
  
              String title = (String) getAttributes().get("title");
              if (title != null) {
                  writer.writeAttribute("title", title, null);
              }
  
          }
      }
  
      @Override
      public void encodeEnd(FacesContext context) throws IOException {
          ResponseWriter writer = context.getResponseWriter();
          writer.endElement("div");
      }
  </code></pre>
  
  <p>This is CommenstTreeTag:</p>
  
  <pre><code>public class CommentsTreeTag extends UIComponentTag {
  
      String style;
      String styleClass;
      String title;
      String width;
      String height;
      String value;
      Long parentId;
  
      public void release() {
          // the super class method should be called
          super.release();
          style = null;
          styleClass = null;
          title = null;
          height = null;
          width = null;
          parentId = null;
          value = null;
      }
  
      @Override
      protected void setProperties(UIComponent component) {
          // the super class method should be called
          super.setProperties(component);
  
          if (style != null) {
              component.getAttributes().put("style", style);
          }
  
          if (styleClass != null) {
              component.getAttributes().put("styleClass", styleClass);
          }
  
          if (width != null) {
              component.getAttributes().put("width", width);
          }
  
          if (height != null) {
              component.getAttributes().put("height", height);
          }
  
          if (title != null) {
              if (isValueReference(title)) {
                  ValueBinding vb =
                          getFacesContext().getApplication().createValueBinding(title);
                  component.setValueBinding("title", vb);
              } else {
                  component.getAttributes().put("title", title);
              }
          }
          if (value != null) {
              if (isValueReference(value)) {
                  ValueBinding vb =
                          getFacesContext().getApplication().createValueBinding(value);
                  component.setValueBinding("value", vb);
                  getFacesContext().getApplication().createValueBinding(value);
  
              } else {
                  component.getAttributes().put("value", value);
              }
          }
          if (parentId != null) {
              component.getAttributes().put("parentId", parentId);
          }
      }
  
  
  
      public String getComponentType() {
          return "commentTree";
      }
  
      public String getRendererType() {
          // null means the component renders itself
          return null;
      }
  
      public String getHeight() {
          return height;
      }
  
      public void setHeight(String height) {
          this.height = height;
      }
  
      public String getWidth() {
          return width;
      }
  
      public void setWidth(String width) {
          this.width = width;
      }
  
      public String getStyle() {
          return style;
      }
  
      public void setStyle(String style) {
          this.style = style;
      }
  
      public String getStyleClass() {
          return styleClass;
      }
  
      public void setStyleClass(String styleClass) {
          this.styleClass = styleClass;
      }
  
      public String getTitle() {
          return title;
      }
  
      public void setTitle(String title) {
          this.title = title;
      }
  
      public String getValue() {
          return value;
      }
  
      public void setValue(String value) {
          this.value = value;
      }
  }
  </code></pre>