I have an issue with the order and number of executions of an f:event type=\"preRenderView\"
.
During my search here I found as usual answers from BalusC
I can reproduce it. This is caused by the presence of /WEB-INF/beans.xml
and implicitly thus CDI. It even occurs when you switch back to standard JSF annotations while keeping the beans.xml
file. This is already reported as both issue 1771 and issue 2162. However, due to absence of a concrete WAR file reproducing the issue and low votes, the Mojarra developers didn't bother to look closer at it.
I have reported it once again as issue 2719. The problem can be reproduced with a smaller example:
<!DOCTYPE html>
<html lang="en"
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"
>
<f:metadata>
<f:event type="preRenderView" listener="#{bean.preRenderView}" />
</f:metadata>
<h:head>
<title>preRenderView fail</title>
</h:head>
<h:body>
<p>On initial request, you'll see the listener being invoked twice instead of only once.</p>
<p>On every postback by the below button, you'll see the listener being invoked once more.</p>
<h:form>
<h:commandButton value="submit" />
</h:form>
<p>Note however that this increments every time you issue the postback.</p>
<p>If you remove <code>/WEB-INF/beans.xml</code> and redeploy, then the issue will disappear.</p>
</h:body>
</html>
and
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class Bean {
public void preRenderView() {
System.out.println("preRenderView called");
}
}
A missing resource may also cause the listener to be called twice. I'm using MyFaces 2.2 here:
<!DOCTYPE html>
<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">
<f:metadata>
<f:event type="preRenderView" listener="#{testController.update()}" />
</f:metadata>
<h:head>
<script type="text/javascript" src="#{resource['/js/missing.js']}" />
<title>Test</title>
</h:head>
<h:body>
<p>TestController.update() is called twice.</p>
</h:body>
</html>
Obviously, you shouldn't include any missing or obsolete resources in the first place. But let's say you have (by mistake) and your listener gets called twice on and on, you have no chance to find the actual cause of that problem. JSF shouldn't do this.