3 Replies Latest reply on Mar 11, 2010 1:45 PM by nbelaevski

    UIViewRoot is null

    r4nd7263

      I am building a HtmlToolBar by code.  For every component I create by code, I get a warning message when view is rendered.

       

      15:32:21,157 WARN  [UIComponentBase] WARNING: Component j_id_jsp_385504039_3:j_id0 just got an automatic id, because there was no id assigned yet. If this component was created dynamically (i.e. not by a JSP tag) you should assign it an explicit static id or assign it the id you get from the createUniqueId from the current UIViewRoot component right after creation! Path to Component: {Component-Path : [Class: org.ajax4jsf.component.AjaxViewRoot,ViewId: /site/Page.jsp][Class: javax.faces.component.html.HtmlForm,Id: j_id_jsp_385504039_3][Class: org.richfaces.component.html.HtmlToolBar,Id: j_id_jsp_385504039_4][Class: org.richfaces.component.html.HtmlDropDownMenu,Id: j_id0]}
      
      

       

      So I made sure to set component id.

       

      HtmlMenuItem item1 = (HtmlMenuItem) facesApp.createComponent(HtmlMenuItem.COMPONENT_TYPE);
      item1.setId(FacesContext.getCurrentInstance().getViewRoot().createUniqueId());
      

       

      The problem I have is that the toolbar renders fine when the page first loads, but if I click a toolbar link, then I get a NullPointerException because UIViewRoot is null.

       

      The managed bean is request scope.

       

      public class PageBean {
      
           private HtmlToolBar htmlToolBar;
      
           public PageBean() {
                UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
                
                buildHtmlToolBar();
           }
           
           private void buildHtmlToolBar() {
                //...
           }
      
           public void setHtmlToolBar(HtmlToolBar htmlToolBar) {
                this.htmlToolBar = htmlToolBar;
           }
      
           public HtmlToolBar getHtmlToolBar() {
                return htmlToolBar;
           }
      }
      

       

      So to be more clear, when page loads the first time, viewRoot is not null.  The page renders ok with a toolbar.  Now if I click toolbar item, then PageBean is initialized again as expected, but viewRoot is null this time, which causes NullPointerException later when in buildHtmlToolBar() method.

       

      I am not sure if this is expected behavior because RichFaces Ajax framework.  What is the solution so I don't get a WARN message nor NullPointerException?  I guess I could assign a static Id for each component, but that's not desirable.

        • 1. Re: UIViewRoot is null
          nbelaevski

          Hi Rand,

           

          So, in the time of PageBean creation, there was no UIViewRoot set up yet. This is normal behavior, you shouldn't create components in bean constructor.

          • 2. Re: UIViewRoot is null
            r4nd7263

            Ok I changed to

             

            public HtmlToolBar getHtmlToolBar() {
                      if (htmlToolBar == null) {
                           buildHtmlToolBar();
                      }
                      return htmlToolBar;
                 }
            

             


            That fixes the problem.  But I realized that on subsequent ajax submit (such as clicking a toolbar item) a new PageBean is instantiated, but getHtmlToolbar() is never called again.  Is this because of ajax framework?  But I have set HtmlMenuItem submitMode to "server", shouldn't it refresh the entire page, thus invoke getHtmlToolbar()?

             

            By the way my Page.jsp looks like

             

            <!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
            <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
            <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
            <%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
            
            <!-- RichFaces tag library declaration -->
            <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
            <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
            
            <html>
                 <head>
                      <title>Page</title>
                 </head>
            
                 <body>
                      <f:view>
                           <t:panelGrid>
                                <t:outputText value="#{PageReq.siteName}"></t:outputText>
                           </t:panelGrid>
                           <h:form>
                                <rich:toolBar binding="#{PageReq.htmlToolBar}"></rich:toolBar>
                           </h:form>
                      </f:view>
                 </body>
            </html>
            
            • 3. Re: UIViewRoot is null
              nbelaevski

              Hi,

               

              "binding" in JSF is processed on 6th phase if component is new, otherwise it's processed on 1st phase and then not re-evaluated unless component tree is rebuilt.