4 Replies Latest reply on Mar 20, 2009 10:05 AM by Stan Silvert

    Managed Bean Problem

    Igor K Newbie

      Hello all.
      I have the following code:

       JSFSession session = new JSFSession("/faces/login.xhtml");;
       session.getJSFClientSession().setValue(":username", username);
       session.getJSFClientSession().setValue(":password", password);
       TransactionBean tb1 = (TransactionBean) session.getJSFServerSession().getManagedBeanValue("#{TransactionBean}");
       session.getJSFClientSession().click("submitButton");
       TransactionBean tb2 = (TransactionBean) session.getJSFServerSession().getManagedBeanValue("#{TransactionBean}");
       assertEquals("home.xhtml", session.getJSFServerSession().getCurrentViewID());

      The problem: tb1 and tb2 are different instances.
      Can anyone help me to understand why does it happens ?

        • 1. Re: Managed Bean Problem
          Stan Silvert Master

          Sometimes a login will create a new session. Check the HttpSession objects returned by jsfClientSession.getFacesContext().getExternalContext().getSession().

          Or, your application might have simply replaced the bean.

          Stan

          • 2. Re: Managed Bean Problem
            Igor K Newbie

             

            "stan.silvert@jboss.com" wrote:
            Sometimes a login will create a new session. Check the HttpSession objects returned by jsfClientSession.getFacesContext().getExternalContext().getSession().

            Or, your application might have simply replaced the bean.

            Stan


            Hello, Stan.
            Login was only for demonstration. In fact, this bug occurs each time when i try to navigate.
            Modified example:
             JSFSession session = new JSFSession("/faces/login.xhtml");
             session.getJSFClientSession().setValue(":username", username);
             session.getJSFClientSession().setValue(":password", password);
             session.getJSFClientSession().click("submitButton");
             TransactionBean tb1 = (TransactionBean) session.getJSFServerSession().getManagedBeanValue("#{TransactionBean}");
             tb1.setCurrentCustomerId(5);
             session.getJSFClientSession().click("customersMenuButton");
             TransactionBean tb2 = (TransactionBean) session.getJSFServerSession().getManagedBeanValue("#{TransactionBean}");
            


            JSF Element:

            <t:commandLink id="customersMenuButton" forceId="true" action="#{ToplevelNavigationBean.customers}" value="#{msgs.navbarCustomers}" />
            
            


            Navigation method:

             public String customers() {
             // some init code
             return "customers_nav";
             }
            


            Faces-navigation:

             <navigation-rule>
             <from-view-id>/*</from-view-id>
            // some code
             <navigation-case>
             <from-outcome>customers_nav</from-outcome>
             <to-view-id>/customers/customers.xhtml</to-view-id>
             <redirect />
             </navigation-case>
            // some code
             </navigation-rule>
            


            There is no any bean replacing in code.

            I noticed, that FacesContext.currentInstance.externalContext.session is modified after navigation, but wrapped StandardSessionFacade - not. Is it normal ?


            • 3. Re: Managed Bean Problem
              Stan Silvert Master

              I think I reproduced your problem. Stay tuned.

              Stan

              • 4. Re: Managed Bean Problem
                Stan Silvert Master

                I'm pretty sure your problem is due to this old bug:
                https://jira.jboss.org/jira/browse/JSFUNIT-164

                So if you have a situation where you call getManagedBeanValue() and the bean does not yet exist, the JSF ManagedBeanELResolver will create an instance of the bean and put it in the HttpSession. However, in JSFUnit, you are not allowed to modify the real HttpSession in your test. That should only be done by the application. So what happens is that the bean created by the test gets put into the fake HttpSession, which doesn't modify the real HttpSession at all. Then you do a request and the same thing happens. Since there is not an instance of the bean in the real session, a new instance is created by the test thread.

                It's going to be tough to fix, but I'll try to get to it in the next few weeks. In the mean time, you can get a reference to the real HttpSession and do an assertion on that. The following code demonstrates the problem.

                assertNotNull(server.getManagedBeanValue("#{TransactionBean}"));
                HttpSession session = (HttpSession)FacesContext.getCurrentInstance()
                 .getExternalContext().getSession(true);
                assertNull(session.getAttribute("TransactionBean"));


                Stan