WELD-001303:Websphere 上没有范围类型 javax.enterprise.context.SessionScoped 的活动上下文

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

我们已升级我们的应用程序以使用 CDI bean。当我们在 Wildfly 10.x 上部署我们的应用程序时,这种变化非常顺利,但是当我们尝试在 Websphere Classic 和 Liberty 上部署相同的应用程序时,出现了一些问题。

我们已经寻找了几个已经发布在这里的问题,例如 this, this, this or this,但是 none 的答案能够解决我们的问题。

在我的本地主机上,我使用带有 webProfile-7.0 的 Websphere Liberty Profile,即 CDI-1.2、EL-3.0、JSF-2.2 和 servlet-3.1。 我们的应用程序还使用 Primefaces 6.0.

phaseListener 出现问题。在其上,我们正在注入一个同时注解了 @Named (javax.inject.Named) 和 @SessionScoped (javax.enterprise.context.SessionScoped) 的 Bean。

当在 phaseListener 上调用注入的变量时,会抛出以下错误。

[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.handleRequest(DynamicVirtualHost.java:315)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1014)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.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

这是我们希望注入的 Session Scoped bean

@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;
    }
}

这里是 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);
        }
    }
}

我也试过添加

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

在 if 语句之前,使用 webSession 而不是 ws,但得到了同样的错误。

我想再次指出,这在 Wildfly 中运行良好,这让我们假设我们正确地实现了代码。此外,我们确定我们正在使用 Java 8 并且服务器支持 JEE7,因此,从我们看过的所有地方来看,我们假设这应该在我们的 Websphere 版本上得到支持。 在 Websphere Classic 9.0 上部署应用程序时,我们遇到了完全相同的问题。

到目前为止我们发现的唯一区别是 Websphere 使用 Myfaces 而 Wildfly 使用 Mojarra。这可能是 Myfaces 中的某种错误吗?我们需要使用任何特定的配置或代码来支持这种事情吗?

如果您需要有关我们实施的更多信息以帮助查明此问题的原因,请告诉我。

跟进这个问题已经晚了 4 年,但是,如果其他人发现它,解决方案应该是在 WebSphere 上将 deferServletRequestListenerDestroyOnError 设置为 true。

或者,如果您使用的是 Liberty,只需将此添加到 server.xml:

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