MrRaymondLee
MrRaymondLee

Reputation: 536

Session Scoped Bean not a Session Scoped Bean

I have a Primefaces JSF project and have my beans annotated with the following:

@Named("reportTabBean")
@SessionScoped
public class ReportTabBean implements Serializable {
...
}

The beans create various tabs, trees, etc. A login using Shiro framework is needed before a user can access the application. For some reason every browser session shares the same tabs, tree, etc. and the state of them. It's like the beans are application scope. I tried different scopes without any luck. The user principal, however, isn't shared. I'm getting the correct logged in user.

I've tried both

@javax.enterprise.context.SessionScoped

and

@javax.faces.bean.SessionScoped

with no luck.

What am I doing wrong?

EDIT

I'm using JDK 1.6.32.

Here's one of the beans:

@Named("reportTabBean")
@ViewScoped
public class ReportTabBean implements Serializable {
    private Map<String, TreeNode>   model; //Accordian menu which I want initiated upfront
    private int                     activeReportTypeIndex;
    private TreeNode                selectedNode;
    ....
    @PostConstruct
    public void createModel() {
        model = treeService.createModel();
    }

    public Map<String, TreeNode> getModel() {
        return model;
    }
    ....
    public void tabIsChanged(TabChangeEvent event) {
        FacesContext context = FacesContext.getCurrentInstance();
        Map<String, String> params = context.getExternalContext().getRequestParameterMap();
        AccordionPanel tabView = (AccordionPanel) event.getComponent();
        String activeIndexValue = params.get(tabView.getClientId(context) + "_tabindex");

        this.activeReportTypeIndex = Integer.parseInt(activeIndexValue);
    }

     public void onNodeSelect(final NodeSelectEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSession(true);

        try {
            tabs.add(new ReportListTab(
                event.getTreeNode().getData().toString(),
                reportService.getReports(
                        ((FolderTreeNodeImpl) event.getTreeNode()).getReportType(),
                        ((FolderTreeNodeImpl) event.getTreeNode()).getFolderID()
                        )
                )
                );
         } catch (HibernateException e) {
           LOGGER.error("[onNodeSelect] HibernateException", e);

           FacesContext.getCurrentInstance().addMessage(":messages",
                new FacesMessage(
                        FacesMessage.SEVERITY_ERROR,
                        "Fatal Error",
                        "Please try again. If the error occurs, please contact the administrator."
                )
                );
        }
 }


}

@ViewScoped is org.omnifaces.cdi.ViewScoped but it doesn't matter what scope I have. It behaves as application scope. If I open the accordion at one point in Chrome logged in as User A, the same point in the accordion of Firefox for User B will also be opened. The accordion menu is defined as follows:

<h:form>                            
        <p:accordionPanel value="#{reportTabBean.model.keySet().toArray()}" var="reportType" activeIndex="#{reportTabBean.activeReportTypeIndex}">

            <p:ajax event="tabChange" listener="#{reportTabBean.tabIsChanged}" />

            <p:tab title="${msg[reportType]}">

                <p:tree value="#{reportTabBean.model[reportType]}" var="node" dynamic="true" 
                    cache="true" selectionMode="single" selection="#{reportTabBean.selectedNode}" id="tree">

                    <p:ajax event="select" update=":tabViewForm" listener="#{reportTabBean.onNodeSelect}" />

                    <p:treeNode type="node" expandedIcon="folder-open" collapsedIcon="folder-collapsed">
                        <h:outputText value="#{node}" />
                    </p:treeNode>

                    <p:treeNode type="leaf" icon="document-node">
                        <h:outputText value="#{node}" />
                    </p:treeNode>

                </p:tree>

            </p:tab>
        </p:accordionPanel>
    </h:form>

Below are my POM dependencies:

<dependencies>
        <!-- OmniFaces -->
        <dependency>
            <groupId>org.omnifaces</groupId>
            <artifactId>omnifaces</artifactId>
            <version>1.6.3</version> <!-- Or 1.7-SNAPSHOT -->
        </dependency>
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>tools</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- R -->
        <dependency>
            <groupId>net.rforge.REngine</groupId>
            <artifactId>REngine</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>net.rforge.Rserve</groupId>
            <artifactId>Rserve</artifactId>
            <version>1.7</version>
        </dependency>

        <!-- Log4J -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <artifactId>log4j</artifactId>
            <groupId>log4j</groupId>
            <type>jar</type>
            <version>1.2.16</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2</version>
        </dependency>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>3.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.1.4.RELEASE</version>
            <!-- will come with all needed Spring dependencies such as spring-core 
                and spring-beans -->
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.1.9.Final</version>
            <!-- will come with Hibernate core -->
        </dependency>

        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>el-impl</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>el-api</artifactId>
            <version>6.0.32</version>
            <type>jar</type>
            <scope>provided</scope>
        </dependency>

        <!-- PrimeFaces -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces-mobile</artifactId>
            <version>0.9.4</version>
        </dependency>

        <!-- JSF -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.1.7</version>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.1.7</version>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
            <version>3.8.1</version>
        </dependency>

        <!-- Oracle -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>ojdbc6</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>xdb</artifactId>
            <version>11.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>xmlparserv2</artifactId>
            <version>11.2.0</version>
        </dependency>

        <!-- Apache Shiro authentication/authorization framework -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-aspectj</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>

Upvotes: 0

Views: 3619

Answers (2)

MrRaymondLee
MrRaymondLee

Reputation: 536

Fixed it! Turns out it's because I'm using Spring I need to use Spring's scope annotations and not JSF.

@Scope("session")

rather then

@SessionScoped

I found the solution from this thread.

Upvotes: 0

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

Since you're using @Named you should use @SessionScoped from javax.enterprise.context package, from CDI.

For some reason every browser session shares the same tabs, tree, etc. and the state of them. It's like the beans are application scope

Every browser tab accessing the same web application will share the same user session, so the @SessionScoped bean is not behaving as @ApplicationScoped. This can be noted if you open the same web application in different browsers e.g. Chrome and Firefox, you will see that you're working with two complete different sessions.

By the description of your problem, you need to use @ViewScoped. If you're working with Java EE 7, you can use this scope that comes with JSF 2.2: @javax.faces.view.ViewScoped. If you're working with Java EE 6 or a prior version, the easiest solution will be using @ViewScoped from OmniFaces (note that you need OmniFaces 1.6 at least), or using @ViewScoped from MyFaces CODI.

Related Q/As:

Upvotes: 2

Related Questions