Details
Description
When PersistentFacesState.redirectTo() is invoked in a push application (such as when added to auctionMonitor with a Thread.sleep() added to one of the getters), the application can fail with a NullPointerException in various places, such as:
javax.faces.FacesException: java.lang.NullPointerException
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:128)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at com.icesoft.faces.webapp.xmlhttp.PersistentFacesState.render(PersistentFacesState.java:176)
at com.icesoft.faces.webapp.xmlhttp.PersistentFacesState.executeAndRender(PersistentFacesState.java:312)
at com.icesoft.faces.async.render.RunnableRender.run(RunnableRender.java:143)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:665)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:690)
at java.lang.Thread.run(Thread.java:637)
Caused by: java.lang.NullPointerException
at com.icesoft.faces.application.D2DViewHandler.renderResponse(D2DViewHandler.java:329)
at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:159)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
... 7 more
This appears to be caused by the locking implementation in redirectTo():
public void redirectTo(String uri) {
warnIfSynchronous();
try {
view.acquireLifecycleLock();
view.installThreadLocals();
view.getFacesContext().getExternalContext().redirect(uri);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
release();
view.releaseLifecycleLock();
}
}
view.releaseLifecycleLock() releases all locks held by the current thread. Unfortunately, the current thread may be in the midst of processing a JSF lifecycle, making it vulnerable to corruption from other (push) threads acting on the same view.
— src/com/icesoft/faces/webapp/xmlhttp/PersistentFacesState.java (revision 19230)
+++ src/com/icesoft/faces/webapp/xmlhttp/PersistentFacesState.java (working copy)
@@ -331,18 +331,23 @@
*
*/
+ public void redirectTo(final String uri) {
warnIfSynchronous();
catch (Exception e)
{ - throw new RuntimeException(e); - }finally
{ - release(); - view.releaseLifecycleLock(); - }+ executorService.execute(new Runnable() {
+ public void run()
+ });
}
/**