eclipse-ee4j / mojarra

Mojarra, a Jakarta Faces implementation
Other
158 stars 107 forks source link

FacesContextImpl.setViewRoot is attempting to recreate the viewMap #5408

Closed pizzi80 closed 3 months ago

pizzi80 commented 4 months ago

Describe the bug

FacesContextImpl is trying to recreate the ViewScope Map ?

 @Override
  public void setViewRoot(UIViewRoot root) {
      assertNotReleased();
      Util.notNull("root", root);

      if (viewRoot != null && !viewRoot.equals(root)) {
          Map<String, Object> viewMap = viewRoot.getViewMap(false);
          if (viewMap != null) {
              viewRoot.getViewMap().clear();  // <--- !!!! shouldn't it be    viewMap.clear()  ???
          }
          RequestStateManager.clearAttributesOnChangeOfView(this);
      }

      viewRoot = root;
  }

This is the exception I found in the server log:

19:53:44.732 ERROR [FacesExceptionFilter] [0317d6dc-1388-41d3-bc73-863d89969192][a.b.c.d] FacesExceptionFilter: An exception occurred during processing servlet request. Error page '/500.xhtml' will be shown.
java.lang.IllegalStateException: getAttribute: Session already invalidated
    at org.apache.catalina.session.StandardSession.getAttribute(StandardSession.java:1059)
    at org.apache.catalina.session.StandardSessionFacade.getAttribute(StandardSessionFacade.java:91)
    at org.jboss.weld.module.web.context.beanstore.http.AbstractSessionBeanStore.getAttribute(AbstractSessionBeanStore.java:102)
    at org.jboss.weld.contexts.beanstore.AttributeBeanStore.get(AttributeBeanStore.java:138)
    at org.jboss.weld.module.web.context.beanstore.http.AbstractSessionBeanStore.get(AbstractSessionBeanStore.java:87)
    at org.jboss.weld.contexts.AbstractContext.get(AbstractContext.java:83)
    at org.jboss.weld.contexts.AbstractContext.get(AbstractContext.java:115)
    at org.jboss.weld.contexts.PassivatingContextWrapper$AbstractPassivatingContextWrapper.get(PassivatingContextWrapper.java:78)
    at org.omnifaces.util.BeansLocal.getInstance(BeansLocal.java:134)
    at org.omnifaces.util.BeansLocal.getInstance(BeansLocal.java:121)
    at org.omnifaces.cdi.viewscope.ViewScopeManager.preDestroyView(ViewScopeManager.java:152)
    at org.omnifaces.cdi.viewscope.ViewScopeManager$Proxy$_$$_WeldClientProxy.preDestroyView(Unknown Source)
    at org.omnifaces.cdi.viewscope.ViewScopeEventListener.processEvent(ViewScopeEventListener.java:49)
    at jakarta.faces.event.SystemEvent.processListener(SystemEvent.java:124)
    at jakarta.faces.event.ComponentSystemEvent.processListener(ComponentSystemEvent.java:109)
    at com.sun.faces.application.applicationimpl.Events.processListeners(Events.java:242)
    at com.sun.faces.application.applicationimpl.Events.invokeListenersFor(Events.java:221)
    at com.sun.faces.application.applicationimpl.Events.publishEvent(Events.java:104)
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:118)
    at jakarta.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:672)
    at jakarta.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:672)
    at jakarta.faces.component.UIViewRoot$ViewMap.clear(UIViewRoot.java:1838)
    at com.sun.faces.context.FacesContextImpl.setViewRoot(FacesContextImpl.java:419)
    at jakarta.faces.context.FacesContextWrapper.setViewRoot(FacesContextWrapper.java:311)
    at org.omnifaces.exceptionhandler.FullAjaxExceptionHandler.renderErrorPageView(FullAjaxExceptionHandler.java:558)
    at org.omnifaces.exceptionhandler.FullAjaxExceptionHandler.handleAjaxException(FullAjaxExceptionHandler.java:433)
    at org.omnifaces.exceptionhandler.FullAjaxExceptionHandler.handle(FullAjaxExceptionHandler.java:382)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:88)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:159)
    at jakarta.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:689)
    at jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:449)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.omnifaces.filter.FacesExceptionFilter.doFilter(FacesExceptionFilter.java:118)
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.omnifaces.filter.CacheControlFilter.doFilter(CacheControlFilter.java:239)
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLessToExtension(FacesViewsForwardingFilter.java:187)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:144)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:130)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.doFilter(FacesViewsForwardingFilter.java:86)
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:597)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
    at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:431)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
    at org.apache.tomcat.util.net.Nio2Endpoint$SocketProcessor.doRun(Nio2Endpoint.java:1683)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:1244)
    at org.apache.tomcat.util.net.Nio2Endpoint.setSocketOptions(Nio2Endpoint.java:328)
    at org.apache.tomcat.util.net.Nio2Endpoint$Nio2Acceptor.completed(Nio2Endpoint.java:468)
    at org.apache.tomcat.util.net.Nio2Endpoint$Nio2Acceptor.completed(Nio2Endpoint.java:404)
    at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:129)
    at java.base/sun.nio.ch.Invoker$2.run(Invoker.java:221)
    at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:113)
    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:63)
    at java.base/java.lang.Thread.run(Thread.java:1583)
BalusC commented 4 months ago

Agreed, but viewRoot.getViewMap() doesn't recreate map when viewRoot.getViewMap(false) returns non-null. It just returns exactly the same map.

Your issue is caused by something else. After invalidating the session it's wise to immediately send a redirect instead of forwarding to a page which possibly requires a session.

pizzi80 commented 4 months ago

viewRoot.getViewMap() actually call viewRoot.getViewMap(true) which seems to recreate the Map, isn't it?

Your issue is caused by something else. After invalidating the session it's wise to immediately send a redirect instead of forwarding to a page which possibly requires a session.

Yes, probably could be my fault , actually I'm using some async actions during normal ajax action on a WebApp that I've migrated from Jsf 2.2 + Seam 2.3 where it was safer to use this pattern bacause all the beans were "@Synchronized"

BalusC commented 4 months ago

No, it doesn't recreate. It only creates the map when it's not created yet. Same idea as request.getSession(true). It also doesn't recreate the session when it already exists. The true flag is merely a signal that it should automatically create when it doesn't exist and thus never returns null. The false flag won't autocreate and thus return null when it doesn't exist.