Using a simplified version of the progress bar example, we can see the unique treatment of View-scoped beans in MyFaces. I instrumented the constructor of the OutputProgressController (annotated with View scope) as well as added logging to a PostConstruct method:
The first time it is needed, the OutputProgressController is created and the PostConstruct method is called as expected:
INFO: BEFORE RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController: constructor called for org.icefaces.demo.basic.progress.OutputProgressController@787f189
@javax.faces.bean.ManagedBean(name=outputProgressController, eager=false)
@javax.faces.bean.ViewScoped()
OutputProgressController.afterConstruction: org.icefaces.demo.basic.progress.OutputProgressController@787f189
OutputProgressController.getPercentComplete:
thread : Thread["http-bio-8080"-exec-69,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@787f189
During the next lifecycle which is caused by clicking the button to start Timer task, you can see the instance has a different hashcode but we've not been instructed that a new instance has been created. This is the reference the timer task will always have:
INFO: BEFORE INVOKE_APPLICATION(5) from /compat-basic/progress.jsf
OutputProgressController.setPercentComplete:
thread : Thread[Timer-14,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@e27fdb9
29-Aug-2011 10:08:37 AM org.icefaces.impl.util.DebugPhaseListener afterPhase
INFO: AFTER INVOKE_APPLICATION(5) from /compat-basic/progress.jsf
29-Aug-2011 10:08:37 AM org.icefaces.impl.util.DebugPhaseListener beforePhase
INFO: BEFORE RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.getPercentComplete:
thread : Thread["http-bio-8080"-exec-71,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@e27fdb9
29-Aug-2011 10:08:37 AM org.icefaces.impl.util.DebugPhaseListener afterPhase
INFO: AFTER RENDER_RESPONSE(6) from /compat-basic/progress.jsf
During the next lifecycle, we get the percent vvalue from an instance that has yet another different hashcode:
INFO: BEFORE RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.getPercentComplete:
thread : Thread["http-bio-8080"-exec-71,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@63b6feb1
29-Aug-2011 10:08:37 AM org.icefaces.impl.util.DebugPhaseListener afterPhase
INFO: AFTER RENDER_RESPONSE(6) from /compat-basic/progress.jsf
The next lifecycle, we see yet another "instance" but the timer thread is setting the percent complete on a previous instance:
INFO: BEFORE RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.getPercentComplete:
thread : Thread["http-bio-8080"-exec-71,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@3d3d2941
29-Aug-2011 10:08:38 AM org.icefaces.impl.util.DebugPhaseListener afterPhase
INFO: AFTER RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.setPercentComplete:
thread : Thread[Timer-14,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@e27fdb9
Again, we are getting from what appears to be a different instance:
INFO: BEFORE RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.getPercentComplete:
thread : Thread["http-bio-8080"-exec-72,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@25bf26fe
29-Aug-2011 10:08:39 AM org.icefaces.impl.util.DebugPhaseListener afterPhase
INFO: AFTER RENDER_RESPONSE(6) from /compat-basic/progress.jsf
Getting from a new instance but setting on the one that the Timer task originally had a reference to:
INFO: BEFORE RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.getPercentComplete:
thread : Thread["http-bio-8080"-exec-72,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@64699c99
29-Aug-2011 10:08:40 AM org.icefaces.impl.util.DebugPhaseListener afterPhase
INFO: AFTER RENDER_RESPONSE(6) from /compat-basic/progress.jsf
OutputProgressController.setPercentComplete:
thread : Thread[Timer-14,5,main]
controller: org.icefaces.demo.basic.progress.OutputProgressController@e27fdb9
This mismatch between the instance that the Timer task has a reference to and the one that the requests are getting the value from continues and explains why the updates to the client never change the value - they are always '0', the default value of a new bean.
Linking to parent Myfaces 2 compatibility case.