2

Environment:

  • PrimeFaces 5.1
  • Mojarra 2.2.2
  • Spring 4.0.2

Current Code:

I have the following XHTML page:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                template="/WEB-INF/pages/main/admin.xhtml">

    <ui:define name="contentBody">
        <p:dataTable widgetVar="weekdayTable"
                     value="#{weekdayList.countries}"
                     var="ctr"
                     styleClass="weekdaysManagementDatatable">

            <p:column width="100"
                      sortBy="#{ctr.desc}"
                      headerText="#{msg['page.admin.weekday.list.country']}">
                <h:outputText value="#{ctr.desc}" />
            </p:column>

            <c:forEach items="#{weekdayList.weekdays}" var="day">
                <c:set var="open" value="#{weekdayList.checkOpen(ctr.id, day.date)}"/>
                <p:column width="20" headerText="#{utils.dateToDayWeek(day.date)}">
                    <h:selectBooleanCheckbox value="#{open}">
                        <p:ajax listener="#{weekdayList.handleDay(ctr.id, day.id)}" />
                    </h:selectBooleanCheckbox>
                </p:column>
            </c:forEach>
        </p:dataTable>
    </ui:define>
</ui:composition>

The associated bean is the following :

@Named("weekdayList")
@Scope("session")
public class AdminWeekdayListController implements Serializable {

    ...

    public boolean checkOpen(String ctrId, Date date) {
        Country ctr = countryDao.getById(ctrId);
        List<WeekDay> list = weekdaysMap.get(ctr);

        if (list == null) {
            return true;
        }

        WeekDay day = new WeekDay();
        day.setDate(date);

        for (WeekDay wd : list) {
            if (wd.compareTo(day) == 0) {
                return wd.isOpen();
            }
        }
        return true;
    }
}

I have another bean which maintains the current page to display and the whole the application is made with AJAX. The user is always on the same page and the content is dynamically loaded.

The problem:

When I reload (F5) the page, all seems to work correctly. But, if I go trought the normal navigation (AJAX loading), I have got a PropertyNotFoundException...

Here is the stack trace:

SEVERE: javax.faces.component.UpdateModelException: javax.el.PropertyNotFoundException: /WEB-INF/pages/main/admin/weekdayList.xhtml @32,47 value="#{open}": /WEB-INF/pages/main/admin/weekdayList.xhtml @29,74 value="#{weekdayList.checkOpen(ctr.id, day.date)}": Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at javax.faces.component.UIInput.updateModel(UIInput.java:867)
    at javax.faces.component.UIInput.processUpdates(UIInput.java:749)
    at org.primefaces.component.api.UIData.process(UIData.java:342)
    at org.primefaces.component.api.UIData.processChildren(UIData.java:323)
    at org.primefaces.component.api.UIData.processPhase(UIData.java:285)
    at org.primefaces.component.api.UIData.processUpdates(UIData.java:271)
    at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:651)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
    at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1254)
    at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:769)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:497)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:610)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:539)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.el.PropertyNotFoundException: /WEB-INF/pages/main/admin/weekdayList.xhtml @32,47 value="#{open}": /WEB-INF/pages/main/admin/weekdayList.xhtml @29,74 value="#{weekdayList.checkOpen(ctr.id, day.date)}": Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:133)
    at javax.faces.component.UIInput.updateModel(UIInput.java:832)
    ... 36 more
Caused by: javax.el.PropertyNotFoundException: /WEB-INF/pages/main/admin/weekdayList.xhtml @29,74 value="#{weekdayList.checkOpen(ctr.id, day.date)}": Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:133)
    at org.apache.el.parser.AstIdentifier.setValue(AstIdentifier.java:129)
    at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:260)
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
    ... 37 more
Caused by: javax.el.PropertyNotFoundException: Property 'checkOpen' not found on type stomac.web.controller.AdminWeekdayListController
    at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:245)
    at javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:222)
    at javax.el.BeanELResolver.property(BeanELResolver.java:332)
    at javax.el.BeanELResolver.getType(BeanELResolver.java:82)
    at com.sun.faces.el.DemuxCompositeELResolver._getType(DemuxCompositeELResolver.java:215)
    at com.sun.faces.el.DemuxCompositeELResolver.getType(DemuxCompositeELResolver.java:242)
    at org.apache.el.parser.AstValue.setValue(AstValue.java:199)
    at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:260)
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
    ... 40 more

But what make me think that the problem does not come from my bean is, if I remove the #{open} from the value of the <h:selectBooleanCheckbox/> it perfectly works (except that the checkboxes are not checked the way I want):

<c:forEach items="#{weekdayList.weekdays}" var="day">
    <c:set var="open" value="#{weekdayList.checkOpen(ctr.id, day.date)}"/>
    <p:column width="20" headerText="#{utils.dateToDayWeek(day.date)}">
        #{open}
        <h:selectBooleanCheckbox value="true">
            <p:ajax listener="#{weekdayList.handleDay(ctr.id, day.id)}" />
        </h:selectBooleanCheckbox>
    </p:column>
</c:forEach>

As you can see I keep using #{open} but not inside the value attibute.

Questions:

What did I wrong? Am I missing something? Is there a bug?

Thanks.

Tiny
  • 27,221
  • 105
  • 339
  • 599
ChibiTomo
  • 484
  • 1
  • 6
  • 15
  • Hi, have you debug your code in order to ensure that any variable is not null when the error is raised? – markosca Apr 23 '15 at 09:20
  • Nothing is null. It's like it cannot understand that `#{open}` is the result of a method... – ChibiTomo Apr 23 '15 at 09:50
  • @Tiny: This is the way the application is done (didn't it is a good way). But tested with `@Controller("weekdayList")`, the result is the same. – ChibiTomo Apr 23 '15 at 12:30

2 Answers2

4

So... I have found a "solution", and respond to my own question.

I added fakes getter and setter for the method checkOpen. So the bean looks like this:

@Named("weekdayList")
@Scope("session")
public class AdminWeekdayListController implements Serializable {

    ...

    public boolean getCheckOpen() {
        return true;
    }

    public void setCheckOpen(boolean b) {
    }

    public boolean checkOpen(String ctrId, Date date) {
        Country ctr = countryDao.getById(ctrId);
        List<WeekDay> list = weekdaysMap.get(ctr);

        if (list == null) {
            return true;
        }

        WeekDay day = new WeekDay();
        day.setDate(date);

        for (WeekDay wd : list) {
            if (wd.compareTo(day) == 0) {
                return wd.isOpen();
            }
        }
        return true;
    }
}

This way JSF thinks checkOpen is a valid (read/write) attribute, BUT calls checkOpen(String ctrId, Date date). It never calls the getter or the setter...

If someone can explain this, I will be gratefull. And if someone has a better solution, I am listening.

ChibiTomo
  • 484
  • 1
  • 6
  • 15
0

its the LifeCycle of Taghandlers and UI components.

JSTL-Tags in JSF do not represent components and never become part of the component tree once the view has been built.

TagHandlers are responsible for building the tree, "Once they have done their job, they expire". this means, they are available only in the View Building Phase. at the other hand UI-Components run in View Rendering Phase.

Rami.Q
  • 2,486
  • 2
  • 19
  • 30