Since 8.5.1 dominoView datasources have had a property dataCache. By default the setting is “full” which means that all the data for all relevant entries and columns is stored in the server-side map of the page. That can impact the size of content held in memory or being written to disk. But there is also another impact, because some data like DateTimes cannot be stored natively in memory or on disk, for the same reason that such Domino objects cannot be stored in viewScope etc. The setting of “id” means it stores just enough information to easily retrieve the relevant entries from the view. But that can have an impact, as I found out today.
The scenario I had was that the view displayed fine, but when I clicked to expand the detail, it threw an error which OpenLog told me was a NullPointerException. For the masochists curious amongst you, the details are in the stack trace at the bottom of the page. The important lines are shown in green.
After a bit of trial and error I identified that the problem wasn’t in the detail area that was being expanded, but on an image which had a rendered property that was calculating based on the current entry’s column value, that was causing a NullPointerException. You can probably see where I was able to confirm that with the stack trace. The other line shown in green confirms that it occurred during the Apply Request Values phase.
Those of you who have seen previous sessions I’ve done will know that rendered property calculates a number of times during the XPages lifecycle. Basically, because I had set dataCache to id, at the end of initially loading the page, the entry was cleared from memory leaving only the id for each entry. When it was calculating the rendered property during the Apply Request Values phase of a partial refresh, the entry had not yet been re-initialised, hence the NullPointerException.
The solution was simple and advisable for performance anyway: Do a check for view.isRenderingPhase() in the rendered property, so if the code was not running in the Render Response phase, just return false.
Hopefully this will prove an interesting lesson for XPages developers who have started to move beyond the basics. It highlights even more than ever that when you get to this stage, understanding the XPages lifecycle is critical for diagnosing issues and very useful when reading stack traces. The relevant phase is always before LifecycleImpl.phase() and LifecycleImpl.execute() , so easy to locate in any stack trace.
javax.faces.FacesException: javax.faces.el.EvaluationException: java.lang.NullPointerException
at com.ibm.xsp.component.UIDataIterator.invokeOnComponent(UIDataIterator.java:1099)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at com.ibm.xsp.component.UIDataPanelBase.invokeOnComponent(UIDataPanelBase.java:416)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at com.ibm.xsp.extlib.component.layout.UIVarPublisherBase.invokeOnComponent(UIVarPublisherBase.java:153)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at com.ibm.xsp.component.UIDataPanelBase.invokeOnComponent(UIDataPanelBase.java:416)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:878)
at com.ibm.xsp.component.UIViewRootEx.invokeOnComponent(UIViewRootEx.java:1552)
at com.ibm.xsp.component.UIViewRootEx._processDecodes(UIViewRootEx.java:1427)
at com.ibm.xsp.component.UIViewRootEx.processDecodes(UIViewRootEx.java:1399)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:98)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:96)
at com.ibm.xsp.controller.FacesControllerImpl.execute(FacesControllerImpl.java:256)
at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:228)
at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:157)
at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1335)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:853)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1319)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:662)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:482)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:350)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:306)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:184)
at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:134)
at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:451)
at javax.faces.component.UIComponentBase.fillShadowedFlags(UIComponentBase.java:880)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1166)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1177)
at com.ibm.xsp.component.UIDataIterator.processDecodes(UIDataIterator.java:783)
at com.ibm.xsp.extlib.component.data.AbstractDataView.processDecodes(AbstractDataView.java:528)
at com.ibm.xsp.component.UIViewRootEx$2.invokeContextCallback(UIViewRootEx.java:1429)
at com.ibm.xsp.component.UIDataIterator.invokeOnComponent(UIDataIterator.java:1096)
… 34 more
Caused by: java.lang.NullPointerException
at com.ibm.xsp.model.domino.wrapped.DominoViewEntry.getColumnValuesEx(DominoViewEntry.java:334)
at com.ibm.xsp.model.domino.wrapped.DominoViewEntry.getColumnValue(DominoViewEntry.java:244)
at com.ibm.xsp.model.domino.wrapped.DominoViewEntry.getValue(DominoViewEntry.java:499)
at com.ibm.xsp.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:132)
at com.sun.faces.el.impl.ArraySuffix.evaluate(ArraySuffix.java:182)
at com.sun.faces.el.impl.ComplexValue.evaluate(ComplexValue.java:163)
at com.sun.faces.el.impl.BinaryOperatorExpression.evaluate(BinaryOperatorExpression.java:175)
at com.sun.faces.el.impl.ExpressionEvaluatorImpl.evaluate(ExpressionEvaluatorImpl.java:257)
at com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:150)
… 43 more