5 Replies Latest reply on Aug 31, 2010 12:30 AM by ruado

    NewEntryNotAllowedException happened when accessing Managed Bean property.

    ruado

      I got this exception when I tried to get the selectionString property of TBean backing bean (its scope is session). My test case looks like this:

       

       

       

      public class ScrollableDataTableTest extends ServletTestCase {
       
          public static TestSuite suite() {
              TestSuite suite = new TestSuite(ScrollableDataTableTest.class);
              return suite;
          }
       
       
          public void testWhenThereAreMoreThanOneRow() throws IOException {
              JSFSession jsfSession = createJSFSession("/scrollableDataTableTest.jsf");
              JSFClientSession clientSession = jsfSession.getJSFClientSession();
              JSFServerSession serverSession = jsfSession.getJSFServerSession();
       
              jsfSession.getWebClient().setAjaxController(new NicelyResynchronizingAjaxController());
       
              // create one row on the table
              clientSession.setValue("rowNum", "2");
              // submit form
              clientSession.click("rowGenerator");
       
              //click the first row of the table
              HtmlTable tbl = (HtmlTable) clientSession.getElement("n");
              //assert table number of row
              assertEquals(tbl.getRowCount(), 2);
              HtmlTableRow row = tbl.getRow(1);
       
              row.click();
       
              TestBackingBean t = (TestBackingBean) serverSession.getManagedBeanValue("#{Tbean.selectionString}");
              System.out.println("String: " + t.getSelectionString());
       
              //click the get table selection button
              clientSession.click("rowSelector");
          }
       
          private JSFSession createJSFSession(String url) throws IOException {
              WebClientSpec wcSpec = new WebClientSpec(url, BrowserVersion.FIREFOX_3);
              wcSpec.getWebClient().setThrowExceptionOnFailingStatusCode(false);
              wcSpec.getWebClient().setThrowExceptionOnScriptError(false);
              JSFSession jsfSession = new JSFSession(wcSpec);
              return jsfSession;
          }
      }
      
      
      

       

      My facelets page looks like this:

       

       

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:rich="http://richfaces.org/rich"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:a4j="http://richfaces.org/a4j">
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
              <title>TODO supply a title</title>
          </head>
          <body>
              <ui:composition template="/template.xhtml">
                  <ui:define name="body">
                      <h:form id="testFrm">
                          <rich:scrollableDataTable
                              id="testTbl"
                              selection="#{Tbean.selection}"
                              value="#{Tbean.products}"
                              var="product"
                              rowKeyVar="tidx">
                              <a4j:support event="onRowClick" reRender="sString">
                                  <f:setPropertyActionListener target="#{Tbean.selectionString}" value="Generated by onclick"/>                            
                              </a4j:support>
                              <rich:column>
                                  <f:facet name="header">
                                      <h:outputText value="Code"/>
                                  </f:facet>
                                  <h:outputText value="#{product.code}"/>
                              </rich:column>
                              <rich:column>
                                  <f:facet name="header">
                                      <h:outputText value="Name"/>
                                  </f:facet>
                                  <h:outputText value="#{product.name}"/>
                              </rich:column>
                          </rich:scrollableDataTable>
                          <h:panelGrid columns="2">
                              <h:inputText value="#{Tbean.generatedRows}" id="rowNum"/>
                              <a4j:commandButton value="Generate Table Content"
                                                 actionListener="#{Tbean.generateTableContent}"
                                                 reRender="testTbl"
                                                 id="rowGenerator"/>
                              <h:outputText value="Selection : #{Tbean.selectionString}" id="sString"/>
                              <a4j:commandButton value="Get Table Selection"
                                                 actionListener="#{Tbean.computeSelection}"
                                                 reRender="sString"
                                                 id="rowSelector"/>
                          </h:panelGrid>
                      </h:form>
                  </ui:define>
              </ui:composition>
          </body>
      </html>
      

       

      I have tried to debug what caused the problem and I found out that on the server side, JSF tried to create another instance of the BackingBean and added it to the sessionMap. However, because the session map of JSFUnit is an instance of NoNewEntryMap, the exception was thrown. Has anyone bumped into the same problem? I use Myfaces 1.2.2, Richfaces 3.3.3.Final.

        • 1. Re: NewEntryNotAllowedException happened when accessing Managed Bean property.
          ssilvert

          Hi,

           

          Can you post your stack trace?

           

          You should never see the NewEntryNotAllowedException in a stack trace.  In JSFServerSession the exception is caught and handled.

           

          If your problem is that

          serverSession.getManagedBeanValue("#{Tbean.selectionString}") 

           

          returns null then JSFUnit is probably working as designed.  You don't want to let your test code inadvertantly create beans.

           

          See https://jira.jboss.org/browse/JSFUNIT-164 for details.

           

          Stan

          • 2. Re: NewEntryNotAllowedException happened when accessing Managed Bean property.
            ruado

            Hi,

             

            Actually, I didn't get this exception, I only spotted it when debugging JSFUnit code base. However, I have still wondered why at this point:

             

             

            serverSession.getManagedBeanValue("#{Tbean.selectionString}") 
            

             

            JSFUnit have to create a new bean instance. The bean instance must have been created and put in the HttpSession after the call to clientSession.click('rowGenerator') method. Is the HttpSession of JSFUnit different from that JSF uses to store beans in my case?

            • 3. Re: NewEntryNotAllowedException happened when accessing Managed Bean property.
              ruado

              I have just found out a workaround, instead of calling:

               

               

              serverSession.getManagedBeanValue("#{Tbean.selectionString}") 
              

               

              My code uses the method Application.evaluateExpressionGet(...) to access the value of selectionString property.

               

              Here is how it looks like:

               

               

              Application app =
                              serverSession.getFacesContext().getApplication();
              String s =
                              (String) app.evaluateExpressionGet(serverSession.getFacesContext(), "#{Tbean.selectionString}", String.class);
              
              
              
              • 4. Re: NewEntryNotAllowedException happened when accessing Managed Bean property.
                ssilvert

                You are free to do that if you want but I think you are probably introducing a bug in your test code.

                 

                The reason getManagedBeanValue() returns null is because there is nothing bound to Tbean as of the last JSF request.  When you make an EL call using Application.EvaluateExpressionGet you are telling JSF to create the bean for you and bind that to the name Tbean.  But this is not something you should do in your test.  A test should not have side effects like that.  You want the session state to only be modified by an HttpRequest into the JSF FacesServlet.

                 

                Stan

                • 5. Re: NewEntryNotAllowedException happened when accessing Managed Bean property.
                  ruado

                  Hi,

                   

                  Actually, there is no new bean instance created when the  Application.EvaluateExpressionGet method is executed. Watch out for this fragment in my xhtml page:

                   

                   

                  <a4j:support event="onRowClick" reRenderer="sString">
                       <f:setPropertyActionListener target="#{Tbean.selectionString}" value="Generated by onclick"/>
                  </a4j:support>
                  

                   

                  After the call of HtmlTableRow.click() method, The value returned from  Application.EvaluateExpressionGet is equal to "Generated by onclick". This result shows that there is no bean created in my test code.