24

I' ve a JSF page that shows the content of a folder (really it's a dropbox's account content).

I'm using a dataTable to render the content of a ListArray object:

<h:dataTable style="text-align: left" width="600" var="dContent" value="#{backedBean.contents}">
  <h:column>
    <f:facet name="header">
      <f:verbatim>NAME</f:verbatim>
    </f:facet>
    <h:commandButton value="#{dContent.fileName}" action="#{backedBean.updateContents(dContent)}"/>
  </h:column>
  <h:column>
    <f:facet name="header">
      <f:verbatim>SIZE</f:verbatim>
    </f:facet>
    <h:outputText value="#{dContent.size}"/>
  </h:column>
</h:dataTable>

But when I run this page I obtain the following error:

/browse.xhtml @34,110 action="#{backedBean.updateContents(dContent)}" Error Parsing: #{backedBean.updateContents(dContent)}
...
...
Caused by: org.apache.el.parser.ParseException: Encountered " "(" "( "" at line 1, column 28. Was expecting one of:
"}" ...
"." ...
"[" ...
">" ...
"gt" ...
"<" ...
"lt" ...
">=" ...
"ge" ...
...
...

The funny thing is that Netbeans is able to autocomplete the method name so I image that my backend bean is ok. The problem occurs only when I call a method with a parameter.

Any ideas?

Many thanks

Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
Neos76
  • 315
  • 1
  • 2
  • 7

3 Answers3

40

Passing method arguments was introduced in EL 2.2. So this is only possible if you're running on a Servlet 3.0 / EL 2.2 capable container like Tomcat 7, Glassfish 3, JBoss AS 6, etc and your web.xml is been declared as per Servlet 3.0 specification.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>
    <!-- Config here -->
</web-app>

If you aren't, then check this answer for alternatives with regard to obtaining current row in datatables, or this answer with regard to replacing the EL implementation by one which supports passing method arguments so that you can use it on Servlet 2.5 / EL 2.1 containers as well.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks a lot, I was investigating just now that probably the reason is that my container (tomcat6) does not support this feature. In fact deploying the app on glassfish v3 the error disappears. Many thanks. – Neos76 Mar 11 '11 at 14:34
  • Just a note: I read that method arguments are supported in JSF 2.0 and Netbeans let me configure this app with tomcat 6 and with JSF 2.0 support. Are JSF 2.0 and EL 2.2 related in some ways? – Neos76 Mar 11 '11 at 14:37
  • 2
    It is not a JSF 2.0 feature. It is an EL 2.2. feature. JSF 2.0 is bundled with Java EE 6 which in turn also bundles Servlet 3.0 / EL 2.2. So it *look like* a JSF 2.0 feature. However, JSF 2.0 is backwards compatible with Java EE 5 which in turn bundles Servlet 2.5 / EL 2.1, yet EL 2.1 doesn't support this. – BalusC Mar 11 '11 at 14:52
3

Jboss Seam can also help to get the feature.

Seam uses JBoss EL which provides an extension to the standard Unified Expression Language (EL). JBoss EL provides a number of enhancements that increase the expressiveness and power of EL expressions.

Example:

pass literal strings using single quotes: <h:commandLink action="#{printer.println('Hello world!')}" value="Hello"/>

or for dynamic value <h:commandButton action="#{hotelBooking.bookHotel(hotel)}" value="Book Hotel"/>

Limitation:

JBoss EL can't currently be used with JSP 2.1 as the compiler rejects expressions with parameters in. So, if you want to use this extension with JSF 1.2, you will need to use Facelets. The extension works correctly with JSP 2.0.

  • It works: I am using Seam 2.2.0.GA, in JBoss 4.2.3.GA and richfaces 3.3.3.Final: my code working: rendered="#{bean.method(StringArgument)}" – Stefano Scarpanti May 05 '17 at 16:24
2

There has actually been a "hack" way of doing this since JSF 1.0. You just create a method on your backing bean that returns a Map, and you can use JSF EL to pass whatever object you want to that method, because JSF thinks that you are passing the key to the map.

Meanwhile, in your backing bean method you actually return an "imposter" map instance that is not really a map at all, whose get() method delegates to the method you wanted to call. In your .xhtml or .jsp file then you can use the square bracket notation to pass the variable.

Extending HashMap is one way to make the imposter map easy to define -- succinct enough to use an anonymous inner class that way.

This is a hack, but it has worked well for me in the past.

Michael Lucas
  • 733
  • 1
  • 8
  • 23