Details
Description
ICEfaces portlets running in Web Space (v10) (which is basically Sun's version of Liferay running on Glassfish) do not work because state saving is not able to restore the view. When running with the default state manager:
<state-manager>
com.icesoft.faces.application.ViewRootStateManagerImpl
</state-manager>
results in:
[#|2009-05-22T20:23:16.361+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=21;_ThreadName=httpSSLWorkerThread-8080-2;|20:23:16,360 ERROR [ViewRootStateManagerImpl:74] Missing ViewRoot in restoreState, ice.session: OSG2uV1W4b-f9acKwYsUFg, viewNumber: 1
|#]
Switching to our other state manager:
<state-manager>
com.icesoft.faces.application.SingleCopyStateManagerImpl
</state-manager>
results in:
[#|2009-05-22T20:30:25.262+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=27;_ThreadName=httpSSLWorkerThread-8080-4;|20:30:25,262 ERROR [SingleCopyStateManagerImpl:145] Session Available, but View State does not exist for viewId:/chat.iface
|#]
Since ICEfaces portlets run fine on other Liferay bundles, there must be something specific to state saving on this particular platform that is causing the problem.
<state-manager>
com.icesoft.faces.application.ViewRootStateManagerImpl
</state-manager>
results in:
[#|2009-05-22T20:23:16.361+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=21;_ThreadName=httpSSLWorkerThread-8080-2;|20:23:16,360 ERROR [ViewRootStateManagerImpl:74] Missing ViewRoot in restoreState, ice.session: OSG2uV1W4b-f9acKwYsUFg, viewNumber: 1
|#]
Switching to our other state manager:
<state-manager>
com.icesoft.faces.application.SingleCopyStateManagerImpl
</state-manager>
results in:
[#|2009-05-22T20:30:25.262+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=27;_ThreadName=httpSSLWorkerThread-8080-4;|20:30:25,262 ERROR [SingleCopyStateManagerImpl:145] Session Available, but View State does not exist for viewId:/chat.iface
|#]
Since ICEfaces portlets run fine on other Liferay bundles, there must be something specific to state saving on this particular platform that is causing the problem.
I found a bug in the Web Space issue tracker related to this issue and added comments that I'll copy here as well:
https://webspace.dev.java.net/issues/show_bug.cgi?id=9
The problem appears to be how the namespaces for portlet session scopes is calculated. The com.sun.portal.portletcontainer.portlet.impl.PortletSessionImpl.class encodes namespaces when it stuffs things into the portlet session:
private String getEncodedAttrName(String name, int scope) {
{ encodedName = name; }String encodedName = null;
if(scope == 1)
else
{ StringBuffer sb = new StringBuffer(); sb.append("javax.portlet.p."); sb.append(WindowIDThreadLocal.get()); sb.append("?"); sb.append(name); encodedName = sb.toString(); }return encodedName;
}
The WindowIDThreadLocal appears to be different depending on the type of request. For a non-Ajax request that actually goes through the portal container (like the initial loading of the portal page), the WindowIDThreadLocal returns a different value than when Ajax requests are made. These Ajax requests do NOT go through the portal container but instead go straight to ICEfaces servlets. I instrumented the ICEfaces MainServlet to print out the request URI and the WindowIDThreadLocal value for each request and was able to verify this. For example:
[#|2009-06-08T22:12:32.934+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=21;_ThreadName=httpSSLWorkerThread-8080-3;|MainServlet.service
-> incoming:
request uri: /chat/chat.iface
window id : chat_WAR_chat_INSTANCE_zwW9_LAYOUT_10817|#]
[#|2009-06-08T22:12:32.981+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=23;_ThreadName=httpSSLWorkerThread-8080-2;|MainServlet.service
-> incoming:
request uri: /chat/block/message
window id : 1_WAR_chatportlet_LAYOUT_10817|#]
[#|2009-06-08T22:12:32.995+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=23;_ThreadName=httpSSLWorkerThread-8080-2;|
MainServlet.service <- outgoing:
request uri: /chat/block/message
window id : 1_WAR_chatportlet_LAYOUT_10817|#]
[#|2009-06-08T22:12:33.114+0000|INFO|sun-appserver2.1|javax.enterprise.system.stream.out|_ThreadID=23;_ThreadName=httpSSLWorkerThread-8080-2;|
MainServlet.service -> incoming:
request uri: /chat/block/message
window id : 1_WAR_chatportlet_LAYOUT_10817|#]
So the request for chat.iface goes through the portal container. Because the window id is different, it gets stored in the session where a subsequent (Ajax/non portal) request is not able to find it. In this case, the view root does not get restored so a new view root is created, giving the appearance that nothing is happening.