By royjavelosa


2011-08-16 14:38:07 8 Comments

Im new to JSF 2. My question is related to BalusC's answer to this question jsf2 ajax update parts based on request parameters I tried the kickstart code BalusC posted and I encountered an EL parsing error:

 /nameofpage.xhtml @12,64 rendered="#{bean.panels.contains('u1')}"
 Error Parsing: #{bean.panels.contains('u1')}

I guess that this is caused because I'm not running a Servlet 3.0 / EL 2.2 capable container with a /WEB-INF/web.xml declared as per Servlet 3.0 spec. I'm using Tomcat 6.

BalusC suggested in his answer to create a custom EL function. But how do I accomplish this using a custom EL function? Or can this be fixed by just configuring certain parts of my project?

Below is my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>    
  </context-param>      
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

1 comments

@BalusC 2011-08-16 14:50:45

First create a final class with a public static method which does exactly the job you want:

package com.example;

import java.util.Collection;

public final class Functions {

    private Functions() {
        // Hide constructor.
    }

    public static boolean contains(Collection<Object> collection, Object item) {
        return collection.contains(item);
    }

}

Then define it as a facelet-taglib in /WEB-INF/functions.taglib.xml:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib 
    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-facelettaglibrary_2_0.xsd"
    version="2.0">
    <namespace>http://example.com/functions</namespace>

    <function>
        <function-name>contains</function-name>
        <function-class>com.example.Functions</function-class>
        <function-signature>boolean contains(java.util.Collection, java.lang.Object)</function-signature>
    </function>
</facelet-taglib>

Then familarize Facelets with the new taglib in the existing /WEB-INF/web.xml:

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/functions.taglib.xml</param-value>
</context-param>

(note: if you already have the javax.faces.FACELETS_LIBRARIES definied, then you can just add the new path semicolon separated)

Then define it in the Facelets XHTML file as new XML namespace:

<html 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:func="http://example.com/functions"
    ...
>

Finally you can use it as intended:

rendered="#{func:contains(bean.panels, 'u1')}"

As a completely different alternative, you can also include JBoss EL in your project. It works on Tomcat 6.0 and you'll be able to invoke non-getter methods in EL. Drop jboss-el.jar file in /WEB-INF/lib and add the following to your web.xml:

<context-param>     
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>   
</context-param>

Since EL 2.2 there's another approach: create an @ApplicationScoped bean with methods in turn referring to those static functions. See also a.o. Utility methods in application scoped bean.

@royjavelosa 2011-08-16 16:33:39

Thanks for the quick reply BalusC !!! I tried the jobss-el.jar approach. The error is now gone, it displays 3 check boxes u1, u2, u3 but when i choose any of them nothing seems to happen (Chrome,Firefox) I also tested in Internet Exporer and after checking any of the check box it says: Webpage error details Message: 'mojarra' is undefined Line: 9 Char: 1 Code: 0 URI: localhost:8080/myproject/ajaxcall.jsf Am I missing anything? Thanks for your patience and thank you in advance BalusC

@BalusC 2011-08-16 16:37:24

You're welcome. Your new question is actually a different question which needs to be asked by Ask Question button on the right top. Your initial question has been answered. Anyway, here's a hint: <h:head>.

@royjavelosa 2011-08-16 16:55:17

Thanks again BalusC the jobss-el.jar approach worked like a charm! I'll ask my new question using the Ask Question.

@Thang Pham 2012-08-22 18:42:38

Hi BalusC. Is there a way to add description to the custom EL, so like when we inside Netbean for example, we can Ctrl + space to show to description of the function?

@BalusC 2012-08-22 19:33:10

Yes, you can use <description> tag for this: <function><description>Your description here.</description>...</function>.

@Thang Pham 2012-08-23 19:27:49

@Thank you BalusC. Just one more question. Can we do custom EL with overload methods. I have two overload methods(same method name, different number of parameters), JSF generates error as below: Function 'util:transform' specifies 2 params, but 1 were declared. I have them as two separated <function>.

@BalusC 2012-08-23 19:29:06

@Thang: no, that isn't possible. Each overloaded EL method must have a different EL function name.

@Thang Pham 2012-08-23 19:33:22

Thank you. That is definitely a very bad limitation on JSF/JSP.

@Roger 2013-01-14 19:33:09

Hello, can I ask when do you recommend which approach? jBoss or the final class etc, etc, etc.? In what do they differ?

@BalusC 2013-01-14 20:16:53

@Roger: JBoss EL saves EL functions boilerplate code. Note that whatever JBoss EL does is also supported in EL 2.2. So if you happen to use Servlet 3.0 / EL 2.2 already, then you can just invoke non-getter methods in EL.

@Cosmin Cosmin 2013-12-19 10:19:50

Hello BalusC, does this work if we don't use facelets for rendering, and we have jsp:root ? I mean if it also works in #{} not in ${}

@BalusC 2013-12-19 10:49:12

@Cosmin: just create a JSP TLD file instead of Facelets taglib XML file. Syntax is very similar. You can find an example of the JSP TLD file at the bottom of our EL wiki page under the section "EL functions": stackoverflow.com/tags/el/info

@Cosmin Cosmin 2013-12-19 10:51:31

yes but I want to use it in Deffered EL, with #{}, not with ${} :(

Related Questions

Sponsored Content

10 Answered Questions

[SOLVED] Static methods in Python?

31 Answered Questions

[SOLVED] What's the difference between a method and a function?

24 Answered Questions

[SOLVED] Why can't static methods be abstract in Java

21 Answered Questions

[SOLVED] Java: when to use static methods

22 Answered Questions

[SOLVED] Why doesn't Java allow overriding of static methods?

1 Answered Questions

[SOLVED] RichFaces faces-config.xml Declaration Errors

1 Answered Questions

[SOLVED] ice:inputRichText is not rendered

  • 2013-09-05 18:25:52
  • Petr DuĊĦek
  • 478 View
  • 0 Score
  • 1 Answer
  • Tags:   jsf maven

1 Answered Questions

[SOLVED] Primefaces charts Error

  • 2011-06-22 09:08:24
  • Ranjith
  • 1302 View
  • 0 Score
  • 1 Answer
  • Tags:   jsf primefaces

Sponsored Content