ArrayIndexOutOfBoundsException for composite component with ajax invocation inside - jsf

My page:
<?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:compo="http://java.sun.com/jsf/composite/test">
<h:head>
</h:head>
<h:body>
<h:form>
<compo:composite changeListener="#{testBean.invoke}"/>
</h:form>
</h:body>
</html>
My composite component:
<?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:composite="http://java.sun.com/jsf/composite"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<composite:interface>
<composite:attribute name="changeListener" required="true"
method-signature="java.lang.Object action(javax.faces.event.AjaxBehaviorEvent)"/>
</composite:interface>
<composite:implementation>
<h:commandButton value="Click">
<f:ajax event="click" listener="#{cc.attrs.changeListener}"/>
</h:commandButton>
</composite:implementation>
</html>
My java bean (prototype scope in spring):
public class Bean {
public void invoke(javax.faces.event.AjaxBehaviorEvent event) {
// some logic
}
}
When I trying to press button, I see
02-Jul-2014 01:24:22.242 WARNING [http-apr-8080-exec-43] com.sun.faces.lifecycle.InvokeApplicationPhase.execute 0
java.lang.ArrayIndexOutOfBoundsException: 0
at org.apache.el.parser.AstValue.convertArgs(AstValue.java:287)
at org.apache.el.parser.AstValue.invoke(AstValue.java:241)
in log. For some cases I've got: java.lang.NumberFormatException: For input string: testBean.invoke So, it is JSF bug or I do something wrong? How I can pass method expression inside composite component?

Looks like JSF bug https://java.net/jira/browse/JAVASERVERFACES-2758
Exceptions are different, but if you opens response in browser, you will see PropertyNotFoundException.
Workaround for me: pass not MethodExpression, but bean and methodName separately and execute listener as
listener="#{cc.attrs.bean[cc.attrs.method]}"

The stack trace it looks like the Apache Expression Language parser form Tomcat (org.apache.el.parser). I think it is this issue: https://bz.apache.org/bugzilla/show_bug.cgi?id=57855 ( Invoke MethodExpression with wrong pram count results in ArrayIndexOutOfBoundsException).

Related

FacesMessge not clearing in WebSphere Liberty server 20.0.0.2

Am developing application using JSF 2.2.16, PrimeFaces 6.2 and WebSphere Liberty server, Now am upgrading Liberty server from 19.0.0.11 to 20.0.0.2. Here am facing issue that FacesMessage not clearing on request. Below is my sample code,
Here is my jsf page 'welcome.xhtml' looks like,
<!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"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h1>Hello World PrimeFaces</h1>
<h:form>
<p:message id="mainMessages" globalOnly="true" autoUpdate="true"/>
<p:commandButton action="#{mainBean.redirect}" value="submit" />
</h:form>
</h:body>
</html>
Here is my 'redirect.xhtml' looks like,
<!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"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h1>Redirect</h1>
<h:form>
<p:message id="mainMessages" globalOnly="true" autoUpdate="true"/>
</h:form>
</h:body>
</html>
below is my sample java code,
#Named(value="mainBean")
#ViewAccessScoped
public class MainBean {
public String redirect(){
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "save");
FacesContext.getCurrentInstance().addMessage(null, message);
return "redirect"
}
}
below is sample navigation-config.xml,
<navigation-case>
<from-action>#{mainBean.redirect}</form-action>
<form-outcome>redirect</form-outcome>
<to-view-id>/pages/redirect.xhtml</to-view-id>
<redirect/>
</navigation-case>
When I click on submit button, it successfully redirected to redirect.xhtml page. But, message was not appeared in screen when am using WebSphere Liberty server 19.0.0.11. But when I Upgrade server to 20.0.0.2. Message getting appear in the screen. I would like to know reason why message appeared in the screen after redirect.

ui:param can't be evaluated in actionListener inside a composite component

If I pass an expression to a composite component like
<My:myButton action="#{bean.myaction()" value="#{bean.buttText()}"
and try to use it in
<cc:implementation>
<h:commandButton actionListener="#{cc.attrs.action} value="#{cc.attrs.value}...
I get the exception "Target Unreachable, identifier 'bean' resolved to null".
But only if bean is a <ui:param name="bean" value="#{myRealBean}"/> inside a template. The error only occours with actionListener. The button text, resolved from the same bean in the same way will be shown.
This old question seems to have the same problem but no answer.
If I split the parameter to
<My:myButton bean="#{bean}" method="myaction" value="#{bean.buttText()}"
and use
<cc:implementation>
<h:commandButton actionListener="#{cc.attrs.bean[cc.attrs.method]()} ...
no error occours and everything works fine.
How can I use a function-expression in an actionListener inside a composite component, where the bean is a <ui:param?
Glassfish 4.1.1, Mojarra 2.2.12
And now, the MCVE
a bean:
package beans;
import java.io.Serializable;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named
#ViewScoped
public class Testbean implements Serializable {
public String getButtText() { return "Submit"; }
public void doAction() { System.out.println("Ajax was here."); }
}
a page
<!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:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ST="http://java.sun.com/jsf/composite/softeam" >
<h:head>
</h:head>
<h:body>
<h:form id="testform">
<h:panelGrid columns="1">
<ui:include src="testtemplate.xhtml">
<ui:param name="bean" value="#{testbean}"/>
</ui:include>
<ST:testButt text="#{testbean.buttText}" action="#{testbean.doAction()}"/>
<h:commandButton value="#{testbean.buttText}" actionListener="#{testbean.doAction()}"/>
</h:panelGrid>
</h:form>
</h:body>
</html>
and a template
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:ST="http://java.sun.com/jsf/composite/softeam">
<ST:testButt text="#{bean.buttText}" action="#{bean.doAction()}"/>
<h:commandButton value="#{bean.buttText}" action="#{bean.doAction()}" />
</ui:composition>
and the component
<!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:S="http://xmlns.jcp.org/jsf/composite" >
<S:interface>
<S:attribute name="action" method-signature="void action()"/>
<S:attribute name="text" type="java.lang.String"/>
</S:interface>
<S:implementation>
<h:commandButton style="display:inline-block"
value="#{cc.attrs.text}"
actionListener="#{cc.attrs.action}"
/>
</S:implementation>
</html>
All buttons will be shown (with the bean.buttText()) but only the second, third and fourth will call the action. The first button throws an exception when clicked.
Edit: Example reduced to JSF, no PrimeFaces components.

JSF - Passing Parameters to a view on click of Button [duplicate]

This question already has answers here:
Creating master-detail pages for entities, how to link them and which bean scope to choose
(2 answers)
Closed 6 years ago.
I am using JSF 2.0 and have a simple TestButton.xhtml like below:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:body>
<h:form>
<h:inputText value="#{employee.empName}"/><br/>
<h:commandButton value="Derive" action="EmployeeTest2" >
<f:param name="Name" value="#{employee.empName}"/>
</h:commandButton>
</h:form>
</h:body>
</ui:composition>
And a Managed bean which is view scoped.
#ManagedBean(name="employee", eager=true)
#ViewScoped
public class Employee implements Serializable{
String empName;
String selectedEmployeeName;
public String getSelectedEmployeeName() {
return selectedEmployeeName;
}
public void setSelectedEmployeeName(String selectedEmployeeName) {
this.selectedEmployeeName = selectedEmployeeName;
}
public Employee() {
super();
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public void manipulate(){
System.out.println("Manipulate called...");
System.out.println(selectedEmployeeName);
this.selectedEmployeeName = this.selectedEmployeeName + " Jr.";
}
Now on click of button, i navigate to EmployeeTest2.xhtml which has following code :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<f:view>
<f:metadata>
<f:viewParam name="Name" value="#{employee.selectedEmployeeName}"/>
<f:event type="preRenderView" listener="#{employee.manipulate}"/>
</f:metadata>
</f:view>
<h:body>
<h:inputText value="#{employee.selectedEmployeeName}"/>
</h:body>
</ui:composition>
i get correctly navigated to EmployeeTest2.xhtml but my parameter value is coming as null. I can see that manipulate method is getting called(sysouts get printed) but selectedEmployeeName is null.
Please advise as to what am i missing.
I already referred to below thread and did same but of no help.
https://stackoverflow.com/questions/20880027/passing-parameters-to-a-view-scoped bean-in-jsf
Update 1: Changed
<h:inputText value="Chris"/>
to
<h:inputText value="#{employee.empName}"/>
Put a breakpoint at setter method for selectedEmployee. Setter is not getting called which means param passing is not working.
Update 2 Please see updated testButton.xhtml
?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:body>
<h:form>
<h:inputText name = "Name" value="#{employee.empName}"/><br/>
<h:commandButton value="Submit" action="EmployeeTest2" >
<f:param name="Name" value="#{employee.empName}"/>
</h:commandButton>
</h:form>
</h:body>
</ui:composition>
The code seems correct, in my opinion you are sending null to the next page because the value of the employee.empName is actually null.
I would debug the getEmpName() method when the TestButton.xhtml is loaded and then additionally check, after you click the button and move on to the next page whether the parameter is present in the url.
UPDATE
Ok the param is actually the value of the input. In that case add name to its definition. You form should look like this:
<h:inputText name="Name" value="#{employee.empName}"/><br/>
<h:commandButton value="Derive" action="EmployeeTest2" />
UPDATE 2
This is a workaround but you can also try this:
#PostConstruct
public void postConstruct(){
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
setSelectedEmployeeName(params.get("Name"));
}

Unicode character not correctly redisplayed in request query string

I wrote this little JSF page:
<?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://xmlns.jcp.org/jsf/html">
<h:head>
<title>What's your Name?</title>
</h:head>
<h:body>
<h1>What's your name?</h1>
<h:form>
<p>Name: <h:inputText value="#{nameController.name}" /></p>
<h:commandButton value="Submit" action="#{nameController.process}" />
</h:form>
</h:body>
</html>
The name property in nameController is simple, with a variable (of type String), a getter, and a setter, just how you would expect. nameController.process passes name as a GET parameter to another JSF page.
But, if I type "ëlmer" as the name, for example, I am redirected to this URL:
http://localhost:8080/NameThing/name.jsf?name=ëlmer
instead of
http://localhost:8080/NameThing/name.jsf?name=ëlmer
How is this caused and how can I solve it?

Trying to change <ui:include> src tag dynamically

I have main page that looks like this:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<p:panel id="panel">
<ui:include src="#{bean.page}">
</ui:include>
</p:panel>
<p:commandButton actionListener="#{bean.changePage}" value="Push" ajax="true" update="panel"/>
</h:form>
</h:body>
</html>
What I want to do is have a bean like this and change dynamically which page is included. This is how bean looks like:
#ManagedBean
#SessionScoped
public class Bean {
private String page = "";
public Bean() {
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public void changePage(ActionEvent e) {
page = "Page.xhtml";
}
}
When I click button Push I want this page to be included:
<?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:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<ui:component>
Hello from facelets
</ui:component>
</h:form>
</h:body>
Problem is that I have to press the button twice for page to be included. How can this be done so when I press the button the first time page is included?
This kind of templating is normally achieved using the <ui:insert> and <ui:define> tags. Check out this page of the Java EE tutorial.

Resources