I can not get an f:ajax listener working on a simplest JSF 2.2 page. Values are assigned, but the listener is deaf. Strangely, the very same code is working perfectly fine if I replace h:selectOneRadio with h:selectOneMenu. Here is the html:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form id="f" >
<h:selectOneRadio id="r" value="#{test.mode}">
<f:selectItem itemValue="One"/>
<f:selectItem itemValue="Two"/>
<f:selectItem itemValue="Three"/>
<f:ajax render="#form" execute="#form" listener="#{test.listener2()}"/>
</h:selectOneRadio>
<br/>
<h:outputText id="out" value="#{test.mode}"/>
</h:form>
</h:body>
</html>
and the bean:
#Named
#SessionScoped
public class Test implements Serializable {
private final static Logger LOG = Logger.getLogger(Test.class.getName());
private String mode;
public String getMode() {
return mode;
}
public void setMode(String mode) {
this.mode = mode;
LOG.info("Mode setter: " + mode);
}
public void listener1(AjaxBehaviorEvent event) throws AbortProcessingException {
LOG.info("Mode listener 1: " + mode);
}
public void listener2() {
LOG.info("Mode listener 2: " + mode);
}
}
Neither of the listener method types are fired for h:selectOneRadio. Making the bean as #ManagedBean and using different ajax event types were to no help either.
The issue appeared after upgrading of Apache Tomee to version 7.0.1 (MyFaces 2.2.10, JSF 2.2). Same problem with MyFaces to 2.2.11.
The web app is bundled inside an ear, no other JSF libraries are loaded, no Primefaces and similar, no servlet filters, no nothing at all - a pure JSF 2.2 application.
Any ideas?
There's a bug in MyFaces, will be fixed in MyFaces 2.2.12.
Should you need an immediate solution, use MyFaces snapshots, they seem to be working fine, just drop them in Tomee's lib folder instead of the stock versions of myfaces-api-* and myfaces-impl-*.
https://issues.apache.org/jira/browse/MYFACES-4068
Related
I'm trying to test the p:growl and p:messages using the attribute autoUpdate, but it doesn't work, it's a very simple code though.
My page (primes.xhtml):
<h:head/>
<h:body>
<h:form>
<p:messages autoUpdate="true"/>
<p:commandButton action="#{dateBean.testErr}"/>
</h:form>
</h:body>
the DateBean class:
#ManagedBean
public class DateBean {
public String testErr(){
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage("test error"));
return null;
}
}
whenever I hit the commandButton the server gives me the following warning:
"WARNING: There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
These unhandled FacesMessages are: - test error"
But messages aren't displayed in the page, neither do the growl.
The newest: Primefaces 7 doesn't support this p:growl and p:messages autoUpdate="true" attribute. Simply it doesn't work, you get the server warning above: "WARNING: There are some unhandled FacesMessages,..."
Use this instead of autoUpdate="true" attribute:
<p:messages>
<p:autoUpdate />
</p:messages>
and this
<p:growl id="growl" showDetail="true" sticky="true">
<p:autoUpdate />
</p:growl>
See also:
PrimeFaces 6.2 - 7.0 Migration guide
I am trying to use Glassfish 4.0 with Java EE 7 XML namespaces to test the sample below.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Title</title>
</h:head>
<h:body>
<h:form>
<ul>
<ui:repeat value="#{appLoad.movieList}" var="movie">
<li>
<h:link value="#{movie.title}" outcome="movie" includeViewParams="true">
<f:param name="id" value="#{movie.id}"/>
</h:link>
</li>
</ui:repeat>
</ul>
</h:form>
</h:body>
</html>
It links to the following page movie.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<f:metadata>
<f:viewParam name="id" value="#{appLoad.movieId}"/>
<f:event listener="#{appLoad.movieDetail()}" type="preRenderView"/>
</f:metadata>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2">
<h:panelGrid columns="1" width="400">
<h:panelGrid columns="1">
Title : <h:outputLabel value="#{appLoad.movie.title}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:form>
</h:body>
</html>
The #{appLoad} backing bean is
#ManagedBean
#RequestScoped
public class AppLoad {
#EJB
private MovieFacade movieFacade;
private Movie movie = new Movie();
private List<Movie> movieList;
private int movieId;
#PostConstruct
public void movieDetail(){
movieList = movieFacade.findAll();
movie = movieFacade.find(movieId);
System.out.println(movieId);
}
// Getters+setters.
}
When the index page is run, and the link is been clicked, the url outrightly changed to
result.xhtml?id=8
But no data is been displayed. Its comes as blank. I figured out that #{appLoad.movieId} is null. In other words, the <f:viewParam> does not set this request parameter.
The only work around I had was to change the XML namespaces back to the older version.
<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:f="http://java.sun.com/jsf/core">
I'm guessing I'm getting something wrong here. How is this problem caused and how am I supposed to use the new XML namespaces?
The way how the new xmlns.jcp.org XML namespaces are been handled is broken in the first Mojarra releases 2.2.0 and 2.2.1. It has been fixed in Mojarra 2.2.2 (note: ticket in the link describes different problem symptom, but under the covers, it's essentially the same cause). It's recommended to upgrade to Mojarra 2.2.2. GlassFish 4.0 has Mojarra 2.2.0 bundled. You can get the JAR from javaserverfaces.java.net. All you need to do is to replace javax.faces.jar file in GlassFish's /modules folder with the newer version.
This kind of trouble is by the way not unusual with the very first major GlassFish release (all hastle to get it ready on time). I recommend to wait with Java EE 7 until GlassFish 4.0.1 or 4.1 has been released to avoid future surprises. Note that other vendors like Apache Tomcat and JBoss AS take their time to release a stable Java EE 7 container; they do currently not have a production ready version yet.
See also:
Using new xmlns.jcp.org namespace on composites causes java.lang.NullPointerException at java.util.concurrent.ConcurrentHashMap.putIfAbsent
I have a Managed Bean in ViewScope mode. So, when I call some action from this Managed Bean my page do not update. I see that my action is invoked well and returning null (viewscope work flow is OK).
So, what am I doing wrong?
If I rerender the page using Ajax it works fine.
EDIT:
My Versions are:
JSF 2.1.14 with Primefaces 3.4.1
My Code:
#ManagedBean(name = "test")
#ViewScoped
public class TestMB implements Serializable {
private String status;
public String getStatus() { return this.status; }
public void setStatus(String status) { this.status = status; }
public String changeStatus() {
this.status = "ViewScope Works!";
return null;
}
}
My page:
<!DOCTYPE HTML>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
template="/template/ui.xhtml">
<ui:define name="head">
</ui:define>
<ui:define id="teste" name="content">
<h:form id="form">
<h:outputText id="status" value="OK?: #{test.status}" />
<p:commandButton id="myAction" value="Do it!" action="#{test.changeStatus}" />
</h:form>
</ui:define>
</ui:composition>
On my screen, the status variable dont change. And, yes.. the action is called OK. Some tip ?
You were using <p:commandButton> to submit the form. It sends by default an ajax request. It updates by default nothing. The behaviour you're observing is thus fully expected. There are several ways to solve this "problem" (quoted, as it's actually not a problem, but just a conceptual misunderstanding):
Tell it to not use ajax.
<p:commandButton ... ajax="false" />
Tell it to update the form.
<p:commandButton ... update="#form" />
Replace by standard JSF component, which doesn't use ajax by default.
<h:commandButton ... />
Note that this concrete problem is unrelated to the view scope itself. You'd have exactly the same problem (with exactly the same solutions) when using another scope, including the request scope.
Some days ago I've changed mojarra to myfaces to solve this problem, now I'm having an strange problem rendering my composite components, they simply aren't rendered the second time I open one popup (the popup is a composite component too).
The first time, as you can see in fieldset, all is rendered ok:
then I click in "CANCELAR" (cancel) button, and the second time, none of my composite components, except the dialog, is rendered:
when I've looked at log, I found these messages:
[#|2012-04-10T15:22:00.681-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2uz|#]
[#|2012-04-10T15:22:00.684-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:inputRazaoSocial|#]
[#|2012-04-10T15:22:00.685-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vi|#]
[#|2012-04-10T15:22:00.685-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vn|#]
[#|2012-04-10T15:22:00.686-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vs|#]
as you can see, the problem is that myfaces can't find a facet in composite component...
The only composite component that uses facets is hrgi:popup:
<c:interface>
<c:attribute name="titulo" default="sem titulo" required="false"/>
<c:attribute name="renderizar" default="false" required="false"/>
<c:attribute name="modal" default="true" required="false"/>
<c:attribute name="bordaConteudo" default="true" required="false"/>
<c:facet name="cabecalho" required="false"/>
<c:facet name="conteudo" required="true"/>
<c:facet name="botoes" required="true"/>
</c:interface>
<c:implementation>
<h:outputStylesheet library="css" name="hrgiPopup.css" target="head"/>
<h:outputStylesheet library="css" name="clearfix.css" target="head"/>
<h:outputScript library="js" name="hrgiPopup.js" target="head"/>
<h:panelGroup layout="block" rendered="#{cc.attrs.renderizar}"
class="hrgi-dialog-panel clearfix">
<h:panelGroup layout="block" class="hrgi-dialog-overlay clearfix" rendered="#{cc.attrs.modal}"></h:panelGroup>
<h:panelGroup id="popup" layout="block" class="hrgi-dialog-box clearfix">
<h:panelGroup layout="block" class="hrgi-dialog-title clearfix">
<h:outputText style="float:left" value="#{cc.attrs.titulo}"/>
</h:panelGroup>
<h:panelGroup layout="block" class="hrgi-dialog-content clearfix">
<c:renderFacet name="cabecalho" required="false"/>
<h:panelGroup layout="block" class="hrgi-dialog-background clearfix"
rendered="#{cc.attrs.bordaConteudo}">
<c:renderFacet name="conteudo" required="true"/>
</h:panelGroup>
<h:panelGroup layout="block" class="clearfix" rendered="#{not cc.attrs.bordaConteudo}">
<c:renderFacet name="conteudo" required="true"/>
</h:panelGroup>
<c:renderFacet name="botoes" required="true"/>
<script type="text/javascript">
cercarEventoTab("#{cc.clientId}:popup");
</script>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
</c:implementation>
Is this a bug of MyFaces?? Mojarra doesn't show any problem like this!
UPDATED
The problem just happens when user clicks "CANCELAR" button... The action call this code to clear the fields and close the dialog:
public void cancelar(ActionEvent evento){
fechar();
UIComponent componente=evento.getComponent().getParent().getParent().getParent();
componente.getFacet("conteudo").getChildren().clear();
}
this code was adapted from the approaches you can see here. In this case, only components inside facet conteudo are recreated. Works fine, except with the my composite components.
The code in MyFaces is ok. The log suggest org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer cannot find the c:implementation entry in your composite component file, Since 2.1.6, some changes were done to prevent use '/' characters inside libraryName (see MYFACES-3454 for details). A web config param (org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME) was added to enable the backward behavior, but note the new behavior is mentioned in a explicit way inside the spec.
If that doesn't work, please try create a simple demo app reproducing the bug and create an issue in MyFaces Issue Tracker. In that way, there are better chances that it could get solved in a future release.
UPDATE
I tried to reproduce it with the information provided without success. The problem is the call to
componente.getFacet("conteudo").getChildren().clear();
That code remove all components inside the facet, and MyFaces is smart enought to remember the components that were removed. When the view is restored, MyFaces algorithm builds the view as in the first request and then remove the components to restore the state correctly. This behavior is expected, so there is no bug in MyFaces code. Instead, I suppose the previous behavior described is a bug in Mojarra, and you should change your code to reset your input components in other way, maybe clearing the values inside the bean, or creating a method expression attribute in your composite component that can be called when cancel operation occur and clear the required input fields. There is a lot of ways to do it.
I don't know why, but after I've created some class to handle exceptions, this problem disappeared...
public class HRGIExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public HRGIExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
#Override
public ExceptionHandler getWrapped() {
return wrapped;
}
#Override
public void handle() throws FacesException {
Iterator i = getUnhandledExceptionQueuedEvents().iterator();
while (i.hasNext()) {
ExceptionQueuedEvent event = (ExceptionQueuedEvent) i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)event.getSource();
Throwable t = context.getException();
try{
t.printStackTrace();
}finally{
i.remove();
}
}
getWrapped().handle();
}
}
and
public class HRGIExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public HRGIExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
#Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler result = new HRGIExceptionHandler(parent.getExceptionHandler());
return result;
}
}
finally I've added this to faces.config:
<factory>
<exception-handler-factory>com.hrgi.web.erp.HRGIExceptionHandlerFactory</exception-handler-factory>
</factory>
Deploying on JBoss AS 7.1.0.Final.
I have a very simple test app. It was working as expected until the other day (famous last words) and is no longer doing the most basic thing, namely setting the value of the input component and using it in the action component. I have stripped this thing down to the basics and can not figure out what is going on.
index.xhtml is here
<!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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>contacts</title>
</h:head>
<h:form>
<h:outputLabel value="Message:" />
<h:inputText value="#{contactView.siteCode}" />
<h:commandButton action="#{contactView.save}" value="Save" />
</h:form>
</html>
ViewScoped bean is here
#Named
#ViewScoped
public class ContactView implements Serializable {
public ContactView() {
}
private String siteCode;
public String getSiteCode() {
System.out.println("getSiteCode: "+ siteCode);
return siteCode;
}
public void setSiteCode(String siteCode) {
System.out.println("setSiteCode: "+ siteCode);
this.siteCode = siteCode;
}
public String save(){
System.out.println("Saving sitecode: " + siteCode);
return "index.jsf";
}
}
What am I doing wrong? When I click on the save button I get this in the output
10:50:37,663 INFO [stdout] (http--0.0.0.0-8080-2) setSiteCode: 22
10:50:37,663 INFO [stdout] (http--0.0.0.0-8080-2) Saving sitecode: null
10:50:37,663 INFO [stdout] (http--0.0.0.0-8080-2) getSiteCode: null
That's because the bean is managed by CDI #Named, not by JSF #ManagedBean. JSF scope annotations of the package javax.faces.bean only works on beans managed by JSF. On a CDI managed bean, you need to use CDI annotations from javax.enterprise.context instead. However, CDI doesn't have a concept of the view scope. Closest is #ConversationScoped, but this is more complex to manage. When you don't specify a scope on a CDI managed bean, it will default to the request scope.
Make sure that your bean is managed by JSF whenever you want to use #ViewScoped.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class ContactView implements Serializable {
// ...
}
Further, you also need to make sure that your action methods return null or void whenever you want to retain the view scope.