omnifaces
omnifaces copied to clipboard
Postconstruct on viewscoped bean is called multiple times
I have a viewscoped bean where the postconstruct method is called multiple times.
public class BBNuevaFacturacion {
public BBNuevaFacturacion() {
}
@PostConstruct
private void initBBNuevaFacturacion() {
}
}
This is the trace from newrelic, the postconstruct method is being called 30 times.
When I use standard JSF javax.faces.view.ViewScoped it works fine. Currently I'm using JSF 2.3 and omnifaces 3.14.3
What's the stack trace of the @PostConstruct call? Have you been able to boil down a reproducer?
No, I haven't been able to reproduce this, it doesn't happen all the time so It's not clear how. The stacktrace of the Postconstruct call is pretty long, what should I look in particular?
Also, I find this weird, in the restoreview phase, another viewscoped bean (BBBuscadorItemBeta) is being initialized a couple times That bean, is also initialized in the postconstruct of BBNuevaFacturacion
The code for that is
public class BBNuevaFacturacion {
public BBNuevaFacturacion() {
}
@PostConstruct
private void initBBNuevaFacturacion() {
bbBuscadorItemBeta = (BBBuscadorItemBeta) FacesUtils.getBBCurrentInstance("bbBuscadorItemBeta");
}
}
//facesutils
public static Object getBBCurrentInstance(String name) {
FacesContext fc = FacesContext.getCurrentInstance();
return fc.getELContext().getELResolver().getValue(fc.getELContext(), null, name);
}
buscadorItemBeta is included as <ui:include src="/pages/buscadores/buscadorItemBeta.xhtml"/> in the xhtml that uses bbnuevafacturacion
I wanted to check if the bean is initializing itself or via another bean in a loop which would then suggest a cyclic dependency and this seems indeed to be the case. Have you tried @Inject instead of manually EL-resolving? CDI is generally smart enough to not trap in a cyclic dependency loop.
I haven't tried with @Inject but I should try.
Now we are using javax.faces.view.ViewScoped and recently we got this log:
25-Sep-2023 13:53:21.087 SEVERE [http-nio-8181-exec-26] com.sun.faces.application.view.FaceletViewHandlingStrategy.handleRenderException Error Rendering View[/pages/facturacion/nuevaFacturacion.xhtml] org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void ar.com.dux.beans.facturacion.BBNuevaFacturacion.initBBNuevaFacturacion() on nz.com.test.beans.facturacion.BBNuevaFacturacion@4625b2a9 at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:85) at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.postConstruct(DefaultLifecycleCallbackInvoker.java:66) at org.jboss.weld.injection.producer.BasicInjectionTarget.postConstruct(BasicInjectionTarget.java:122) at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:164) at org.jboss.weld.util.bean.IsolatedForwardingBean.create(IsolatedForwardingBean.java:45) at com.sun.faces.application.view.ViewScopeContextManager.createBean(ViewScopeContextManager.java:145) at com.sun.faces.application.view.ViewScopeContext.get(ViewScopeContext.java:137) at org.jboss.weld.contexts.PassivatingContextWrapper$AbstractPassivatingContextWrapper.get(PassivatingContextWrapper.java:84) at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:100) at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50) at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:694) at org.jboss.weld.module.web.el.AbstractWeldELResolver.lookup(AbstractWeldELResolver.java:107) at org.jboss.weld.module.web.el.AbstractWeldELResolver.getValue(AbstractWeldELResolver.java:90) at org.jboss.weld.environment.servlet.util.ForwardingELResolver.getValue(ForwardingELResolver.java:49) at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:62) at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:180) at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:208) at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:93) at org.apache.el.parser.AstValue.getValue(AstValue.java:136) at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189) at org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50) at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:115) at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:200) at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:187) at javax.faces.component.UIOutput.getValue(UIOutput.java:179) at javax.faces.component.UIInput.getValue(UIInput.java:311) at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:105) at org.primefaces.util.ComponentUtils.getValueToRender(ComponentUtils.java:69) at org.primefaces.component.inputswitch.InputSwitchRenderer.encodeMarkup(InputSwitchRenderer.java:65) at org.primefaces.component.inputswitch.InputSwitchRenderer.encodeEnd(InputSwitchRenderer.java:59) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949) at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:88) at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:70) at org.primefaces.component.column.ColumnRenderer.encodeEnd(ColumnRenderer.java:64) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912) at org.primefaces.component.panelgrid.PanelGridRenderer.encodeGridBody(PanelGridRenderer.java:294) at org.primefaces.component.panelgrid.PanelGridRenderer.encodeGridLayout(PanelGridRenderer.java:112) at org.primefaces.component.panelgrid.PanelGridRenderer.encodeEnd(PanelGridRenderer.java:56) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912) at org.primefaces.component.panelgrid.PanelGridRenderer.encodeGridBody(PanelGridRenderer.java:294) at org.primefaces.component.panelgrid.PanelGridRenderer.encodeGridLayout(PanelGridRenderer.java:112) at org.primefaces.component.panelgrid.PanelGridRenderer.encodeEnd(PanelGridRenderer.java:56) at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912) at javax.faces.render.Renderer.encodeChildren(Renderer.java:176) at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1905) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908) at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908) at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:491) at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:194) at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151) at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151) at org.omnifaces.viewhandler.OmniViewHandler.renderView(OmniViewHandler.java:155) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:126) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:223) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at nz.com.test.jsf.filters.CacheFilter.doFilter(CacheFilter.java:27) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at nz.com.test.jsf.filters.SecurityFilter.conresultado(SecurityFilter.java:104) at nz.com.test.jsf.filters.SecurityFilter.doFilter(SecurityFilter.java:86) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:89) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.omnifaces.filter.GzipResponseFilter.doFilter(GzipResponseFilter.java:187) at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:364) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:624) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1650) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:750) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor2076.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:83) ... 95 more Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed at org.apache.catalina.connector.Request.doGetSession(Request.java:3088) at org.apache.catalina.connector.Request.getSession(Request.java:2508) at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:896) at com.sun.faces.context.SessionMap.getSession(SessionMap.java:240) at com.sun.faces.context.AlwaysPuttingSessionMap.put(AlwaysPuttingSessionMap.java:55) at com.sun.faces.context.AlwaysPuttingSessionMap.put(AlwaysPuttingSessionMap.java:47) at nz.com.test.utils.FacesUtils.setSessionValue(FacesUtils.java:80) at nz.com.test.utils.Utils.desconectarError(Utils.java:80) at nz.com.test.utils.MessageManager.addToMessages(MessageManager.java:57) at nz.com.test.beans.facturacion.BBNuevaFacturacion.initBBNuevaFacturacion(BBNuevaFacturacion.java:375)
It is weird, because It is trying acces a Postconstruct method
Ah there is finally the root cause I was looking for:
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:3088)
at org.apache.catalina.connector.Request.getSession(Request.java:2508)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:896)
at com.sun.faces.context.SessionMap.getSession(SessionMap.java:240)
at com.sun.faces.context.AlwaysPuttingSessionMap.put(AlwaysPuttingSessionMap.java:55)
at com.sun.faces.context.AlwaysPuttingSessionMap.put(AlwaysPuttingSessionMap.java:47)
at nz.com.test.utils.FacesUtils.setSessionValue(FacesUtils.java:80)
at nz.com.test.utils.Utils.desconectarError(Utils.java:80)
at nz.com.test.utils.MessageManager.addToMessages(MessageManager.java:57)
at nz.com.test.beans.facturacion.BBNuevaFacturacion.initBBNuevaFacturacion(BBNuevaFacturacion.java:375)`
Your problem can be solved with by using <f:viewAction> instead of @PostConstruct to add a FacesMessage. See also the answer to this question: https://stackoverflow.com/q/10197277. In the answer, replace "before the message component is rendered" by "before the response is committed" to get a clear picture. It basically boils down to the same. In your specific case the session wasn't yet created at the moment the code tries to add a faces message, but the response was already committed and therefore it's too late to create the session.
Can that error generate all those calls to the postconstruct method?
Summarized: an ideal error page shouldn't reference any beans which potentially throw uncaught exceptions. Otherwise you could get caught in an awkward loop.
Closing off.