This is another one of those cases where I'm not actually sure what's going on, but I'll make a few observations in the hopes that it will help.
First of all, remember JSF Rule #1: The more JSF-specific you solution is, the more likely it's a bad solution.
I don't think I have a single JSF webapp that uses actionListeners. There is a use for them, but 99.999998% of the time, a simple POJO action method is all that you need. Especially since in your example, I'm not sure your listener method has the right signature.
I'm guessing that you want the menu to alter itself. Rather that an complex running around in the JSF internals, I'd use a binding if I needed access to the UI component or its related menu items and if the map is supposed to be retrieving JSF managed beans, I'd simply inject them as managed properties. JSF is all about Inversion of Control, where you don't go looking for things, things are delivered to you automatically.
Incidentally, you don't need to code a method at all in JSF to navigate to a fixed target. You can just do this:
Or if you want to use faces-config, this is something I do a lot:
In which case, just code the following:
Customer surveys are for companies who didn't pay proper attention to begin with.
Given I use the filename directly in the p:menuItem like you suggested, then my pageForwardBean is practically pointless. Yet is the cleanupSessionAttribute() method needed? Because I do this to prevent too much object in stack or memory / session avoiding errors like StackOverflowError.
Yep, the pageForwardBean is redundant here. Another case where JSF tries to minimize the amount of coding you need to do.
As far as memory goes...
Stack space is not an issue. The stack grows and shrinks with the methods that are invoked. So simply returning from the methods frees up the stack memory. If you have a stack overflow, it's usually due to excessive (if not infinite) recursion.
Heap space is a different matter. The JSF View scope was created to help with that. So was J2EE Request scope, but as I've often mentioned, Request scope doesn't work well in JSF.
All View scope really is is Session scope with an automatic free-up mechanism. JSF2 also added a custom scope mechanism, when you need something in between View scope and full Session scope. It's very badly explained, but the gist of it is that if you have a workflow where you are juggling a set of beans to get the job done, you can put them in a private dictionary (Map) and add logic to clear out the map when the workflow is done. As raw as it is, I expect (hope) that eventually a cleaner approach will eventually be developed.
In the mean time, I usually have a method in my catch-all JSFUtils bean that can accept a backing bean as an argument and will then remove it from the HttpSession. Since the bean doesn't actually get deleted at that time, I have unhooked it from the session - meaning that after I've finished with my request, it's eligible for garbage collection - but I can continue to execute within the bean. Normally I have a "cancel" action method that handles this, and it's invoked internally as well for non-cancel operations that have finished using the bean and want to clean up. Since the cancel method may be bypassed (for example, if the user directly jumps to a new URL, there's also an init() method that contains the code to reset the bean's state if it's about to be re-used but wasn't deleted and then re-created.
The (POJO) action method version of returning to the home page looks like this:
If you have a ViewExpiredException, there are ways of handling that, although it sounds more like you are dealing with a stale View that's out of sync. You might could fix it using some of the documented recovery techniques, but if you're writing strange listeners or otherwise putting kinks in the normal JSF lifecycle processing, it might get complicated.
Actually the IOOBE doesn't happen just at the menu items but any other page link and ajax call (eg update select one menu)
In fact in my app there is a ExceptionHandler to handle so-called FacesException like ViewExpiredException, which forward to some error page with stack trace. Yet in the beginning of the project, that error page once in a while pops up. But towards the end of the project, if it did try to get to the error page StackOverflowError occurs. This is weird to me.
Anyhow the StackOverflowError seldomly happens unless 1) session timed out AND 2) the page's managed bean is session scoped and 3) user physically refresh the page like clicking back button.