For command links (and perhaps other components but this would require more analysis to verify), MyFaces renders out different event handling code for onclick depending on whether or not <f:ajax> is enabled for the command link:
MyFaces <h:commandLink>
with <f:ajax>
<a href="#" onclick="jsf.util.chain(document.getElementById('theLink'), event,'jsf.ajax.request(\'theLink\',event,
{\'javax.faces.behavior.event\':\'action\'}
)'); return false;" ...
without <f:ajax>
<a href="#" onclick="return myfaces.oam.submitForm('theForm','theLink');" ...
Mojarra does this as well but it doesn't appear to impact the behaviour adversely.
Mojarra <h:commandLink>
with <f:ajax>
<a id="theLink" href="#" onclick="mojarra.ab(this,event,'action',0,0);return false" ...
without <f:ajax>
<a href="#" onclick="mojarra.jsfcljs(document.getElementById('theForm'),
{'theLink':'theLink'}
,'');return false" ...
Typically, when running with ICEfaces, standard components are automatically "Ajax-ified" without having to actually include the <f:ajax> tag. Because there is no f:ajax tag, MyFaces renders out the non-Ajax version of the onclick handler for the command link. This handler leads to running specific client-side logic for the commandLink component. Logic that assumes a standard full-page type submission.
Because of this different code path, it impacts the requests on the MyFaces client request queue. Timing issues created by push requests can lead to not submitting the required information for the commandLink action to get fired. In the case of commandLink, the hidden field containing the id of the command link is cleared before the request generated by clicking on the commandLink gets sent. When the form is finally serialized, it's missing the crucial bit of information needed to trigger the action.
We saw something similar in Mojarra where, because of queueing, requests needed to be serialized when the click happens rather than just before they are sent or the data can be stale. According to comments in Mojarra's client code, it specifically encodes the form only when sent because the viewid can change on every request.
/**
- Sends an Ajax request
*/
send : function() {
try {
//we have to encode at send time, otherwise
//we pick up old viewstates
The workaround is to add the <f:ajax> tag to the commandLink in order to have MyFaces render out the Ajax version of the handler. As noted, commandLink is currently the only known component where this occurs. And though there is similar behaviour with Mojarra, it doesn't appear to have any detrimental impact.
Linking to parent Myfaces 2 compatibility case.