primefaceswebspherecdijsf-2.2phaselistener

WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped on Websphere


We have upgrade our application to use CDI beans. This change was very smooth when we are deploying our application on Wildfly 10.x, but when we tried to deploy the same application on Websphere Classic and Liberty some problems came up.

We have look for several questions already posted here, like this, this, this or this, but none of the answers were able to solve our problem.

On my localhost I am using Websphere Liberty Profile with webProfile-7.0, meaning CDI-1.2, EL-3.0, JSF-2.2 and servlet-3.1. Our application also uses Primefaces 6.0.

The problem occurs on a phaseListener. On it, we are injecting a Bean annotated with both @Named (javax.inject.Named) and @SessionScoped (javax.enterprise.context.SessionScoped).

When the injected variable is called on the phaseListener the following error is thrown.

[err] 2017-05-10 09:45:06 ERROR MWExceptionHandler:139 - A server exception occurred
org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:691)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164)
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
at web.frmwrk.mgbean.WebSession$Proxy$_$$_WeldClientProxy.getLocale(Unknown Source)
at web.frmwrk.application.LocaleFaceletViewHandler.calculateLocale(LocaleFaceletViewHandler.java:43)
at javax.faces.application.ViewHandlerWrapper.calculateLocale(ViewHandlerWrapper.java:76)
at org.apache.myfaces.application.ResourceHandlerImpl.getLocalePrefixForLocateResource(ResourceHandlerImpl.java:715)
at org.apache.myfaces.application.ResourceHandlerImpl.createViewResource(ResourceHandlerImpl.java:1609)
at org.apache.myfaces.application.ResourceHandlerImpl.createViewResource(ResourceHandlerImpl.java:62)
at javax.faces.application.ResourceHandlerWrapper.createViewResource(ResourceHandlerWrapper.java:83)
at javax.faces.application.ResourceHandlerWrapper.createViewResource(ResourceHandlerWrapper.java:83)
at javax.faces.application.ResourceHandlerWrapper.createViewResource(ResourceHandlerWrapper.java:83)
at javax.faces.application.ResourceHandlerWrapper.createViewResource(ResourceHandlerWrapper.java:83)
at org.apache.myfaces.view.facelets.impl.DefaultResourceResolver.resolveUrl(DefaultResourceResolver.java:53)
at org.apache.myfaces.view.facelets.impl.DefaultResourceResolver.resolveUrl(DefaultResourceResolver.java:39)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.viewExists(FaceletViewDeclarationLanguage.java:325)
at org.apache.myfaces.shared.application.DefaultViewHandlerSupport.checkResourceExists(DefaultViewHandlerSupport.java:573)
at org.apache.myfaces.shared.application.DefaultViewHandlerSupport.handleSuffixMapping(DefaultViewHandlerSupport.java:507)
at org.apache.myfaces.shared.application.DefaultViewHandlerSupport.calculateViewId(DefaultViewHandlerSupport.java:113)
at org.apache.myfaces.application.ViewHandlerImpl.deriveLogicalViewId(ViewHandlerImpl.java:122)
at javax.faces.application.ViewHandlerWrapper.deriveLogicalViewId(ViewHandlerWrapper.java:112)
at javax.faces.application.ViewHandlerWrapper.deriveLogicalViewId(ViewHandlerWrapper.java:112)
at javax.faces.application.ViewHandlerWrapper.deriveLogicalViewId(ViewHandlerWrapper.java:112)
at javax.faces.application.ViewHandlerWrapper.deriveLogicalViewId(ViewHandlerWrapper.java:112)
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:225)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:196)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:143)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1290)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:778)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:475)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:148)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:79)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:1021)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1143)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:1381)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.include(WebAppRequestDispatcher.java:541)
at com.ibm.ws.webcontainer.webapp.WebApp.sendError(WebApp.java:4265)
at com.ibm.ws.webcontainer.webapp.WebApp.handleException(WebApp.java:5031)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:5011)
at com.ibm.ws.webcontainer31.osgi.webapp.WebApp31.handleRequest(WebApp31.java:525)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.handleRequest(DynamicVirtualHost.java:315)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1014)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:280)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:967)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:359)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:318)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:471)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:405)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:285)
at com.ibm.ws.http.channel.internal.inbound.HttpICLReadCallback.complete(HttpICLReadCallback.java:66)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:504)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:574)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:929)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1018)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
[ERROR   ] SRVE0777E: Exception thrown by application class 'javax.faces.webapp.FacesServlet.service:230'
javax.servlet.ServletException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:230)
at [internal classes]
Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:691)
at [internal classes]
at web.frmwrk.mgbean.WebSession$Proxy$_$$_WeldClientProxy.getLocale(Unknown Source)
at web.frmwrk.application.LocaleFaceletViewHandler.calculateLocale(LocaleFaceletViewHandler.java:43)
at javax.faces.application.ViewHandlerWrapper.calculateLocale(ViewHandlerWrapper.java:76)
... 1 more

Here is Session Scoped bean we wish to inject

@Named("ws")
@SessionScoped
public class WebSession extends LoggableBean {
    private static final long serialVersionUID = 5L;

    @Inject
    protected WebApplication wa;

    /** True if session originates from a trusted logon */
    private boolean trusted = false;

    /**
     * Current user, null if not logged in (this may be a simulated user token if {@link #simulateUser(int)} was called
     * before.
     */
    private ISofTokenType userToken;

    /**
     * Original login user (identical to userToken if not simulating another user
     */
    private ISofTokenType loginUserToken;

    /** Current locale of the websession. */
    private Locale locale;

    /** The policy rules resolver for this session */
    private transient PolicyResolver policy;

    @Inject
    protected Config config;

    @Inject
    protected WebPaths path;

    @Inject
    protected WebApplicationStore waStore;

    @PostConstruct
    protected void init() {
        try {
            setLocale(LocaleUtils.getDefaultLanguage().getCode());
        } catch (ConfigurationException ex) {
            // Fallback to default language in config.xml
            getLog().error(ex);
            locale = FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
        }
    }

    /**
     * Check if the currentRelease session is linked with a logged in user or if the visitor is a guest.
     * 
     * @return True if the user is logged in, false otherwise.
     */
    public boolean isLoggedIn() {
        return userToken != null;
    }
}

And here the phaseListener

public class PolicyController implements PhaseListener {
    private static final long serialVersionUID = 2189917635371117541L;

    private static final Log log = LogFactory.getLog(PolicyController.class);
    private static final String VALIDATION_ERROR_DEFAULT_KEY = "validation_error_default";
    private static final String COMPONENT_ATTRIBUTE_RENDERED_MODIFIED_BY_RULE = "rendered-modified-by-policy";

    private static enum PhaseMoment {
        BEFORE, AFTER
    };

    @Inject
    private WebSession ws;

    public void beforePhase(PhaseEvent event) {
        if (!FacesHelper.getConfig().getBoolean(Properties.POLICY_CONTROLLER_ENABLED, true)) {
            if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) log.debug("Policy is disabled");
            return;
        }

        if ((event.getPhaseId() == PhaseId.RENDER_RESPONSE || event.getPhaseId() == PhaseId.PROCESS_VALIDATIONS)
                && ws.isLoggedIn()) { // <- Error happens here
            // Apply the rules...
            FacesContext fc = event.getFacesContext();
            log.debug("Run PolicyController before " + event.getPhaseId() + " (viewroot has "
                    + fc.getViewRoot().getChildCount() + " direct children)");
            traverseComponent(fc, fc.getViewRoot(), event.getPhaseId(), PhaseMoment.BEFORE);
        }
    }

    public void afterPhase(PhaseEvent event) {
        if (!FacesHelper.getConfig().getBoolean(Properties.POLICY_CONTROLLER_ENABLED, true)) {
            return;
        }

        if ((event.getPhaseId() == PhaseId.PROCESS_VALIDATIONS || event.getPhaseId() == PhaseId.RESTORE_VIEW)
                && ws.isLoggedIn()) { // <- Error happens here
            FacesContext fc = event.getFacesContext();
            log.debug("Run PolicyController after " + event.getPhaseId() + " (viewroot has "
                    + fc.getViewRoot().getChildCount() + " direct children)");
            traverseComponent(fc, fc.getViewRoot(), event.getPhaseId(), PhaseMoment.AFTER);
        }
    }
}

I've also tried adding

FacesContext context = event.getFacesContext();
WebSession webSession = context.getApplication().evaluateExpressionGet(context, "#{ws}", WebSession.class);

before the if statement and use webSession instead of ws, but got the same error.

Once again, I would like to point that this is working fine in Wildfly, which lead us to assume we are implementing the code correctly. Also, we are sure we are using Java 8 and the server supports JEE7, so, from all the places we've looked we were assuming this should be something to be supported on our version of Websphere. We have the exact same problem when deploying the app on Websphere Classic 9.0.

The only difference we find so far is that Websphere uses Myfaces while Wildfly uses Mojarra. Can this be some kind of bug in Myfaces? Is there any specific configuration or code we need to use to support this kind of things?

If you need more info about our implementation that may help to figure out the cause of this, just let me know what.


Solution

  • Following up on this issue 4 years too late, but, in case others find it, the solution should be to set deferServletRequestListenerDestroyOnError as true on WebSphere.

    Or just add this to the server.xml if you're on Liberty:

    <webContainer deferServletRequestListenerDestroyOnError="true" />

    https://www.ibm.com/support/pages/apar/PI26908

    A explanation of this property can be found here: https://github.com/OpenLiberty/open-liberty/issues/18281#issuecomment-1353399402