1

I m getting the following exception when trying to display a h:dataTable using the backing bean

javax.faces.el.MethodNotFoundException: javax.el.MethodNotFoundException: /table.xhtml @29,36 action="#{user.editEmployee}": Method not found: com.jason.jsf.User@1df228e.editEmployee()
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
javax.faces.component.UICommand.broadcast(UICommand.java:311)
javax.faces.component.UIData.broadcast(UIData.java:912)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

When executing the following code with these files as i am new to jsf and i m learning please help with some explanation

Employee.java

 package com.jason.jsf;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "employee", eager = true)
@SessionScoped
public class Employee {

    private String Id, name;
    private boolean canEdit;

    public Employee() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Employee(String id, String name) {
        super();
        Id = id;
        this.name = name;
    }

    public String getId() {
        return Id;
    }

    public void setId(String id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isCanEdit() {
        return canEdit;
    }

    public void setCanEdit(boolean canEdit) {
        this.canEdit = canEdit;
    }

}

Here is my User.java

    package com.jason.jsf;

import java.util.ArrayList;
import java.util.Arrays;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "user", eager = true)
@SessionScoped
public class User {

    private static final long serialVersionUID = 1L;

    private String name;
    private String id;

    private static final ArrayList<Employee> employees = new ArrayList<Employee>(
            Arrays.asList(new Employee("John", "Marketing"), new Employee(
                    "Robert", "Marketing"), new Employee("Mark", "Sales"),
                    new Employee("Chris", "Marketing"), new Employee("Peter",
                            "Customer Care")));




    public ArrayList<Employee> getEmployees() {
        return employees;
    }

     public String addEmployee() {
     Employee employee = new Employee(name, id);
     employees.add(employee);
     return null;
     }

     public String deleteEmployee(Employee employee) {
     employees.remove(employee);
     return null;
     }

      public String editEmployee(Employee employee){
          employee.setCanEdit(true);
          return null;
       }

       public String saveEmployees(){
          //set "canEdit" of all employees to false 
          for (Employee employee : employees){
             employee.setCanEdit(false);
          }     
          return null;
       }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

}

Here is my table.xhtml

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <title>JSF tutorial</title>
    <h:outputStylesheet library="css" name="style.css" />
</h:head>
<h:body>
    <h:form>
        <h:dataTable value="#{user.employees}" var="emp"
            styleClass="employeeTable" headerClass="employeeTableHeader"
            rowClasses="employeeTableOddRow,employeeTableEvenRow">
            <h:column>
                <f:facet name="header">Name</f:facet>
                <h:inputText value="#{emp.name}" size="10" rendered="#{emp.canEdit}" />
                <h:outputText value="#{emp.name}" rendered="#{not emp.canEdit}" />
            </h:column>
            <h:column>
                <f:facet name="header">ID</f:facet>
                <h:inputText value="#{emp.id}" size="20" rendered="#{emp.canEdit}" />
                <h:outputText value="#{emp.id}" rendered="#{not emp.canEdit}" />
            </h:column>
            <h:column>
                <f:facet name="header">Edit</f:facet>
                <h:commandButton value="Edit" action="#{user.editEmployee}"
                    rendered="#{not emp.canEdit}">
                </h:commandButton>
            </h:column>
        </h:dataTable>
        <br />
        <h:commandButton value="Save Employees" action="#{user.saveEmployees}" />

    </h:form>
</h:body>
</html>

I have referred different similar questions but didn't get an answer appropriate to my problem. Please help me with the solution

Thanks in advance.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Jason
  • 129
  • 1
  • 5
  • 19

2 Answers2

5

As far as I can see, the editEmployee(Employee employee) method has a parameter of type Employee, however you're not passing a value for this parameter and that's why it tries to invoke a method with the same name, but with no parameters.

Since there is no such, it throws a MethodNotFoundException.

And since you're using JSF 2.0+, you can pass the parameter like this:

<h:commandButton value="Edit" action="#{user.editEmployee(emp)}"
                 rendered="#{not emp.canEdit}">
</h:commandButton>
Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
  • one more query can i pass the parameter some other way rather than passing it in the action itself ? – Jason May 14 '15 at 05:46
  • Well...you can use `actionListener` instead of action. See [this thread](http://stackoverflow.com/questions/3909267/differences-between-action-and-actionlistener) – Konstantin Yovkov May 14 '15 at 05:48
3

Too many times to count, I've had MethodNotFoundException, when clearly, the method is publicly available on the bean. If I temporarily specify a different existing method for the action or actionListener, JSF will find that different method.

Clean build and deploy is insufficient; I have to drastically rename and move the "missing" method, then clean build, and then the "missing" (but now renamed) method is found. Once it works, I change the renamed method back to its original "missing" name, then clean build, and then the former "missing" method is no longer missing.

I'd sure like to know what causes this annoying problem with Eclipse Kepler 4.3.0.

J Slick
  • 929
  • 11
  • 17
  • Same for me, spent an hour looking for an error that did not exist. But in my case close and open Eclipse (Mars) solved the problem. – Allan Veloso Jul 25 '15 at 16:01
  • You said "error that did not exist". I sometimes will be working on a Java class, when the IDE decides that it can't resolve any of the declared imports and then plasters red X icons throughout the active edit window. However, my Ant build script will still clean and rebuild the project, and it runs alright on the server. I remove all the red X error icons via menu Project::Clean::Clean All Projects. Very annoying. – J Slick Jul 26 '15 at 23:59