Facelet Method call where property required - jsf-2

Is it possible to invoke a method where property is expected in JSF 2.0 Facelet EL. For example:
<h:outputText value="#{pojo.methodName}" />
where pojo is an instance of POJO and methodName is the name of method. An error would be thrown because JSF expects to find getMethodName method.
Before someone asks why one would need this, consider any value we want to display in text which is computed and we don't have required getter method and no source code.
Update after BalusC Answer:
No rename possible because no source code available. methodName() didn't work. The only difference is that in actual code its chained pojo.
<h:outputText value="#{pojo1.pojo2.methodName()}" />
Since other properties are working for pojo2, I assume that its methodName which can not be invoked. Server says "The class does not have the property methodName"
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
Empty faces-config
<faces-config 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-facesconfig_2_0.xsd"
version="2.0">
</faces-config>
P.S. environment JBoss 6 and JSF 2

Add parentheses:
<h:outputText value="#{pojo.methodName()}" />
(which only works in EL 2.2, which is part of Java EE 6, so it only works out box in Tomcat 7, Glassfish 3, etc, see also Invoke direct methods or methods with arguments / variables / parameters in EL)
Or just rename the method:
public String getMethodName() {
// ...
}

Related

Primefaces PrimeExceptionHandlerELResolver within Spring Boot

i have a web application with Spring Boot 1.2.4(web,security,data-jpa), Primefaces 5.2 , JSF 2.2 (Mojarra 2.2.11) without any xml config file.
Only faces-config.xml for spring bean el resolver :
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
<!--el-resolver>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver
</el-resolver-->
</application>
<!--factory>
<exception-handler-factory>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerFactory
</exception-handler-factory>
</factory-->
</faces-config>
and all work fine.
Now, i want to handle the ViewExpiredException with primefaces exception handler :
http://www.primefaces.org/docs/api/5.2/org/primefaces/application/exceptionhandler/PrimeExceptionHandlerELResolver.html
My question is : can i register another el-resolver in faces-config.xml ? and if no, how can i fix the problem ?
thanks in advance.
EDIT :
i decide to use another aproche. many thanks to Session Timeout handling for Ajax calls
You can define multiple el-resolver in application node as shown below:
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
<el-resolver>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver
</el-resolver>
</application>

Custom taglib results in MethodNotFoundException

What I want to do is declare a common datatable header as a composite component. But this answer set me straight since it was not rendered:
How to create a composite component for a datatable column?
Basically it instructed me to try my own taglib and this works really well except my header has a link in it that does reRender. When this link is pressed MethodNotFoundException is thrown.
This is my custom taglib:
<?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://stackoverflowdummy.com/dumb/components</namespace>
<tag>
<tag-name>tableHeader</tag-name>
<source>tags/tableHeader.xhtml</source>
<attribute>
<description></description>
<name>value</name>
</attribute>
<attribute>
<description>The listener that handles sorting</description>
<name>sortAction</name>
<method-signature>java.lang.String action()</method-signature>
</attribute>
<attribute>
<description>The property that holds the current id to sort on
</description>
<name>sortValue</name>
</attribute>
<attribute>
<description>The component that needs to be updated after changes
</description>
<name>reRender</name>
</attribute>
</tag>
</facelet-taglib>
I tried without method-signature and I also tried removing "action". My web.xml does include the taglib like this:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/cc.taglib.xml</param-value>
</context-param>
I also tried with "facelets.LIBRARIES" but it made no difference.
<h:commandLink value="#{o.label}" action="#{sortAction}" immediate="true" reRender="#{reRender}">
<f:setPropertyActionListener target="#{sortValue}" value="#{o.column.sortId}" />
</h:commandLink>
End usage is defined like this:
sortAction="#{myBean.sort}"
That bean has a method called with signature String sort(); and it works really well if I just define it and skip using my own tag. However everything works with the tag except the action method...
The JavaBean Specification gives multiple ways on how to call a method. In fact, you can call a action the normal way #{actionBean.actionMethod}, but also the way #{actionBean['actionMethod']}.
The sorting Action you are giving is transferred as a MethodExpression, which compared to ValueExpressions gave me problems in some JSF Environments.
What I'd like you to try testwise is, to give the action as two separate (value) parameters:
sortActionBean="#{myBean}"
sortActionMethod="sort"
and call those in the template as #{sortActionBean['sortActionMethod']}. A good article on this topic is Passing action methods facelets tags.
Hope it helps...

parsing error while including taglib

I'm trying to use Apache Commons Lang 3 in my JSF 2 application, and I followed BalusC's example
But when I included this line in my .xhtml page :
<%#taglib prefix="f" uri="/WEB-INF/functions.tld" %>
I have an error while parsing the page code.
How can I fix the problem?
The answer was targeted on a question whose asker is known to use JSF 1.x on JSP. The syntax which you've there is specific to JSP, the legacy predecesor of Facelets which is deprecated since JSF 2.0.
Get rid of the functions.tld file altogether. The proper JSF 2.x Facelets way of declaring a custom function based on an existing static method is as follows:
First create a /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>escapeJavaScript</function-name>
<function-class>org.apache.commons.lang.StringEscapeUtils</function-class>
<function-signature>java.lang.String escapeJavaScript(java.lang.String)</function-signature>
</function>
</facelet-taglib>
Then register it in /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>
(that step is unnecessary when it is placed in /META-INF of a JAR file which is in turn placed in /WEB-INF/lib)
Finally declare and use it as follows:
<html ... xmlns:func="http://example.com/functions">
...
<h:outputScript>var foo = '#{func:escapeJavaScript(bean.foo)}';</h:outputScript>
Note that I've updated the answer you found accordingly. Also note that this function is already provided out the box as #{of:escapeJS(bean.foo)} by JSF utility library OmniFaces, in case you're using it.

Managed Bean Annotation doesn't work in JSF 2.0

I've encoutered strange issue with annotations in bean.
index.xhtml content:
<h:outputText value="#{ejb.helloWorld}" />
Ejb.java content:
package bean;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name="ejb")
#SessionScoped
public class Ejb implements Serializable
{
public String getHelloWorld()
{
return "Hello World";
}
}
From what we see above i should be able to call bean method... but i can't, it will work only if i manage bean in faces-config.xml file with content:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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-facesconfig_2_0.xsd"
version="2.0">
<managed-bean>
<managed-bean-name>ejb</managed-bean-name>
<managed-bean-class>bean.Ejb</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Questions:
Why i have encountered such situation ?
How to resolve this issue ?
I'm using:
JSF 2.0 (imported to lib)
JBoss Server 4.2
My wild guess is that JSF 1.2 bundled by default with JBoss 4.2 is used (JBoss might not care about JSF version). As a result annotations are ignored, faces-config.xml file is used.
Try to use configuration suggested here (thats's google cached page).

Issues while Upgrading Jsf1.0 to Jsf2.0

While upgrading application to Jsf2.0 created in Spring3 and Jsf1.0 (myfaces), i am facing some issues mentioned below.
I have done following steps to upgrade the application.
From IntelliJ IDEA:
* Open project settings/Monitor/Dependencies
* Removed facelet*jar, el*.jars, myfaces* jars from project
* Added jsf2.0.x ri mojarra jars and tomahawk1.1.9.jar
* Open project settings/monitor/web settings
* Under "modules and libs to package": remove el-.jars,facelet-jar and myfaces jars
* Added jsf2.0.x ri mojarra jars and tomahawk1.1.9.jar
* Removed erroneous class usages from our classes Lists.java and RegExValidator.java. In Lists.java, replace import with org.apache.commons.lang.LocaleUtils. In RegExValidator, replace import with "org.apache.myfaces.shared_tomahawk.util.MessageUtils".
Edit Web.xml:
* facelets.VIEW_MAPPINGS -> javax.faces.FACELETS_VIEW_MAPPINGS
* facelets.LIBRARIES -> javax.faces.FACELETS_LIBRARIES
* Change Faces Servlet to <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
* Change header to:
<web-app version="2.5"
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_2_5.xsd">
Edit faces-config.xml:
* Add header:
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-facesconfig_2_0.xsd"
version="2.0">
* Remove line "<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>"
After doing all the steps mentioned above getting the following error:
A literal value was specified for attribute actionListener that is defined as a deferred method with a return type of void. JSP.2.3.4 does not permit literal values in this case
Actually Jsf2.0 el expressions #{myBean.property} are not getting resolved thats why its showing the above error.
Can anybody guide me, what is missing, so that i can successfully migrate application to Jsf2.0
Thanks in Advance,
Dhillon
A literal value was specified for attribute actionListener that is defined as a deferred method with a return type of void. JSP.2.3.4 does not permit literal values in this case
This EL validation error means that you've somewhere a
<h:commandButton actionListener="somestring" />
instead of
<h:commandButton actionListener="#{someBean.actionListener}" />
or
<h:commandButton action="somestring" />
(instead of h:commandButton you can also read any UICommand component like h:commandLink)
Just locate/lookup the culprit in the code and fix it accordingly.
Upgrade web-app version="3.0" to latest. Previously web-app version is 2.5 at that time I got error, after upgrade to 3.0 issue resolved.
<?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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Resources