IllegalStateException when trying .getSessionMap () from a Scope Bean session

I am new to Java and JSF. I need help with IllegalStateException. Here's the script:

In my current project, I have this Scoped bean session for the application menu:

public final class MenuBean implements Serializable{ private MenuModel model; private FacesContext context = FacesContext.getCurrentInstance(); public MenuModel getModel() { return model; } public MenuBean() { updateMenu(); } public void updateMenu(){ Map session = (Map<String,Object>) context.getExternalContext().getSessionMap(); EUser user = (EUser) session.get(UserBean.USER_SESSION_KEY); ... } private MethodExpression createMethodExpression(String action) { ... } } 

At some point in my logic, I need to update the menu, so I do this:

 ExternalContext extContext = context.getExternalContext(); Map sMap = (Map<String,Object>) extContext.getSessionMap(); MenuBean menu = (MenuBean) sMap.get("menuBean"); menu.updateMenu(); 

The bean construct is fine, but when I try to manually update it as shown above, I get an IllegalStateException in the first line of the updateMenu() update method

I do not understand what is wrong, since I can get a session map with the same call when the menu is created for the first time.

Also, using the NetBeans debugger, I see that the MenuBean instance is correctly restored.

Can you guys help me?

+1
source share
1 answer

FacesContext is stored in the HTTP request stream. You should absolutely not declare and assign it as an instance variable of an instance that lives longer than an HTTP request (and preferably also just not when it already requests based on - a bad design). The FacesContext instance FacesContext freed and FacesContext when the HTTP request completes. In any subsequent HTTP request, the instance is no longer valid. There are funds from an illegal state. This explains the IllegalStateException you see.

You need to delete the following line:

 private FacesContext context = FacesContext.getCurrentInstance(); 

And correct your code so that it is only threadlocal in the method block:

 Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); // ... 

You can always assign it as a variable, but you only need to save this threadlocal:

 FacesContext context = FacesContext.getCurrentInstance(); Map<String, Object> sessionMap = context.getExternalContext().getSessionMap(); // ... 

Unrelated to the specific issue, using @ManagedProperty was easier in this particular case.

 public final class MenuBean implements Serializable { @ManagedProperty("#{user}") private EUser user; // ... } 

JSF will then introduce it for you.

+2
source

All Articles