-
1. Re: PortletStateHolder
wesleyhales Jun 11, 2009 9:40 AM (in response to felderr)No need to double post. We are looking at this issue for next release. Thanks for all the debugging!
-
2. Re: PortletStateHolder
felderr Jun 11, 2009 4:47 PM (in response to felderr)Hi Wesley,
thanks for your quick response! Can you post the Jira or forum link of the double post?
I need to fix the problem this week as we go live next wednesday. My solution is to use a PortletFilter that removes all entries in the LRU Map:public void doFilter(RenderRequest renderRequest, RenderResponse renderResponse, FilterChain chain) throws IOException, PortletException { chain.doFilter(renderRequest, rww); PortletStateHolder stateHolder = (PortletStateHolder)config.getPortletContext().getAttribute(PortletStateHolder.class.getName()); stateHolder.cleanLRUMap(); }
Do you see any drawback when clearing the LRUMap after the Render Phase?
I'm still not clear why the state is hold across requests? -
3. Re: PortletStateHolder
felderr Jun 12, 2009 6:21 AM (in response to felderr)Just implemented the filter and the clearing of the states LRUMap. As I can see all the normal Request/Responses work fine. The Problem occurs when using Ajax based Richfaces requests (eg ExtendedDataTable with filtering and sorting):
javax.faces.FacesException: No saved portlet window state for an id 4c4fd449-3557-426b-8cd5-f864c24692be:view:2cfaa740-1be3-46a4-bef4-28ece52dcd46
at org.jboss.portletbridge.context.ServletExternalContextImpl.(ServletExternalContextImpl.java:101)
So now that I know why the states are cached I have a better solution solving the Memory Leak! The PortletStateHolder needs to hold the state as long as one page is doing Ajax based requests. So if the next page is requested PortletStateHolder does not need the old state any more so it can clearly remove it! So when adding a new WindowState we remove the old WindowStates for this session id:private void clearExpiredSessionStates(String sessionId) { if (states != null && sessionId != null) { for (StateId stateid : states.keySet()) { if (sessionId.equals(stateid.getScopeId())) { states.remove(stateid); } } } } public void addWindowState(StateId stateId, PortletWindowState state) { clearExpiredSessionStates(stateId.getScopeId()); states.put(stateId, state); }
There's one drawback with this solution if there is more than one window open one of the windows get an error when doing Ajax based requests as we only store one state per session.
Working on a solution to this. Any ideas?