Search code examples
jsfuicomponentsmethodexpression

Create MethodExpression containing a method with parameter of type Object generates parse exception


  • I am building a MethodExpression directly via java code.
  • It will represents a call to a bean method with parameter like follow .
#{bean.method(TheObjectInstance)}
  • The object is a simple custom pojo object
public class TheObject
{
   public String value0 = "value0";
}
  • We now create the MethodExpression like follow.
    TheObject object = new TheObject();

    FacesContext context = FacesContext.getCurrentInstance();
    Application application = context.getApplication();
    ExpressionFactory factory = application.getExpressionFactory();

    //Create method expression
    MethodExpression methodExpression = factory.createMethodExpression(
       context.getELContext(), 
       "#{bean.method(" + object + ")}", 
       null, 
       new Class<?>[] {TheObject.class});
  • It generates the following error.
javax.servlet.ServletException: Encountered "@" at line 1, column 87.
Was expecting one of:
    "." ...
    "(" ...
    ")" ...
    "[" ...
    "," ...
    ";" ...
    ">" ...
    "gt" ...
    "<" ...
    "lt" ...
    ">=" ...
    "ge" ...
    "<=" ...
    "le" ...
    "==" ...
    "eq" ...
    "!=" ...
    "ne" ...
    "&&" ...
    "and" ...
    "||" ...
    "or" ...
    "*" ...
    "+" ...
    "-" ...
    "?" ...
    "/" ...
    "div" ...
    "%" ...
    "mod" ...
    "+=" ...
    "=" ...
  • I tried the same code with a String as parameter and a Boolean object and it works fine but using a custom Object is generating the same error, as well if we pass a complex object for instance a UIComponent.

  • I am using JSF 2.2, any helps is welcome.


Solution

    • To create a MethodExpression with a bean method containing an object as parameter #{bean.method(object)}, we should use the name of a var declared in the HTML page var=object.
        <h:form>
         <h:datatable var="object" value="#{bean.objects}">
          <h:commandbutton value="test" actionlistenner="#{bean.method(object)}"/>
        </h:datatable>
        </h:form>
    
    • If we want to generate the same MethodExpression #{bean.method(object)} we will have to generate the full html elements including a parent html element in our case a datatable containing the reference to the object var=object then in the code of the MethodExpression
        //Wrong implementation: the object is converted as object.getClass().toString()
        MethodExpression methodExpression = factory.createMethodExpression(
           context.getELContext(), 
           "#{bean.method(" + object + ")}", 
           null, 
           new Class<?>[] {TheObject.class});
    
        //Right implementation: we refer to object referenced by the datatable var. 
        MethodExpression methodExpression = factory.createMethodExpression(
           context.getELContext(), 
           "#{bean.method(object)}", 
           null, 
           new Class<?>[] {TheObject.class});