0

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>
MrRaymondLee
  • 546
  • 5
  • 12

2 Answers2

2

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:

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • I did try in 2 different browsers and logged into the web app as 2 different users but still saw the issue. It was even the case on different computers. I'll try the @ViewScoped option. I'm using Java EE 6. Would OmniFaces conflict with PrimeFaces? – MrRaymondLee Dec 17 '13 at 06:19
  • @raylee OmniFaces won't conflict with PrimeFaces since OmniFaces is a JSF utility library. In fact, the OmniFaces showcase is written using JSF and PrimeFaces (and OmniFaces as well) – Luiggi Mendoza Dec 17 '13 at 14:25
  • I implemented @ViewScoped from OmniFaces but the issue with sharing states still persists. – MrRaymondLee Dec 17 '13 at 15:42
  • @raylee then the problem seems to be that you are using `static` variables in your class. Please update your question and add the relevant code to reproduce the error. – Luiggi Mendoza Dec 17 '13 at 16:11
  • the only static variables are the log4j logger and the `serialVersionUID`. There are no errors. It's just that trees, accordians, and tabs mirror their content (i use dynamic content) and state. each page uses several beans. i made the scope the same across the beans. will update the question in a bit with some code and my pom. maybe libraries are conflicting? – MrRaymondLee Dec 17 '13 at 16:58
  • have a look please. Hopefully that's enough information. I really don't know what's going on. Is the scope annotation being ignored and application scope the default? – MrRaymondLee Dec 17 '13 at 18:03
0

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.

Community
  • 1
  • 1
MrRaymondLee
  • 546
  • 5
  • 12