]
Marcel Kolsteren commented on RF-13706:
---------------------------------------
I'm afraid that the extra _readyToSubmit_ check breaks my solution. The requestDelay
determines how long an entry should stay at the end of the queue, waiting to be combined
with similar requests. If we're removing stale entries from the queue, and we
encounter the last entry in the queue which is still waiting to get combined, we should
remove it from the queue if it is stale. Otherwise it will cause problems at the time
it's actually submitted.
As Pavol said, I developed the fix for the 4.3 version, and there the unit test ran fine.
Today I merged my original patch to the 4.5 version, and the unit test failed over there.
But the root cause had nothing to do with my original fix, but with the fact that the
_richfaces_ variable has been renamed to _rf_ in 4.5, so that _richfaces.getDomElement_
does not work any more. Changing it to _rf.getDomElement_ fixed the unit test.
dequeued Ajax request not processed correctly if its source element
has been updated
------------------------------------------------------------------------------------
Key: RF-13706
URL:
https://issues.jboss.org/browse/RF-13706
Project: RichFaces
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: core
Affects Versions: 4.3.7
Reporter: Marcel Kolsteren
Assignee: Marcel Kolsteren
Fix For: 4.3.8, 4.5.0.Alpha3
Attachments: queuetest-javaee6.zip, queuetest.zip,
richfaces-core-4.3.8-SNAPSHOT.patch.zip
Original Estimate: 1 hour
Remaining Estimate: 1 hour
I found a problem in the RichFaces Ajax queuing mechanism, which can cause all JavaScript
execution to stop, leaving the end user with an unresponsive page.
The problem occurs when a request in the queue rerenders an area that includes the source
element of the next request in the queue, but does not include the form of that source
element. When the next request is fetched from the queue, JSF tries to find the correct
form by climbing the DOM tree, starting at the source element of the event. However,
because the source element has been rerendered, the path to its form is broken, and in
that case JSF falls back to the first form of the page (see JavaScript function getForm
that is called by jsf.ajax.request in jsf.js). If that form is not the form belonging to
the rerendered version of the element, nasty things will happen.
To illustrate this, I created a very simple Java EE 7 web application (see attached Maven
project) and deployed it in WildFly 8.1.0.Final. It contains a page with one clickable
link that rerenders itself when clicked:
{noformat}
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j">
<h:head/>
<h:body>
<form action="http://www.meandi.nl"/>
<h:form>
<a4j:commandLink action="#{richBean.waitThreeSeconds}"
value="Click Me" render="@this"/>
</h:form>
</h:body>
</html>
{noformat}
The method "waitThreeSeconds" does nothing but waiting for three seconds. When
the link is double clicked, you'll observe that the first click is handled correctly,
but that the second click results in an Ajax request posted to the URL of the first form,
leading to access denied errors (because of cross domain scripting). The used RichFaces
version is 4.3.7.
The problem can be fixed by changing the RichFaces JavaScript code, so that after
completion of an Ajax request, stale elements are removed from the queue. I created a
patch for RichFaces 4.3.7, and verified that it works (see attachment). Another solution
strategy would be to try to find the new DOM element that corresponds to the stale source
of the event, and fetch the form from that element. My thought was that removing the stale
request would be better, because (1) it is kind of dangerous to process a user action on
an element that has already been replaced and (2) the element might have been removed from
the DOM tree by the previous rerender.