Websocket CdiUtils NPE 使用 <f:websocket/> [英] Websocket CdiUtils NPE using <f:websocket />

查看:33
本文介绍了Websocket CdiUtils NPE 使用 <f:websocket/>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此应用程序在 TC7、Spring 3 和 JSF 2.2 中运行良好,但我想添加 JSF 2.3 的推送功能,因此我升级到 TC 9.0.8、Spring 5.0.5 和 JSF 2.3.0 一段时间后由于升级而导致的简单初始问题该应用程序部署良好,Spring Security 工作正常(我可以登录),但随后出现此错误:

This application has been working fine in TC7, Spring 3, and JSF 2.2 but I wanted to add the push capabilities of JSF 2.3 so I upgraded to TC 9.0.8, Spring 5.0.5, and JSF 2.3.0 After some simple initial problems due to the upgrades The app deploys fine and Spring Security works (I can login) but then I get this error:

May 11, 2018 2:24:06 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/index.xhtml]
java.lang.NullPointerException
    at com.sun.faces.cdi.CdiUtils.getBeanReferenceByType(CdiUtils.java:230)
    at com.sun.faces.cdi.CdiUtils.getBeanReference(CdiUtils.java:213)
    at com.sun.faces.renderkit.html_basic.WebsocketRenderer.encodeEnd(WebsocketRenderer.java:111)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912)
    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 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 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
    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:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:412)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1385)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

我的调试器显示 CdiUtils:230 上的 beanManager 为 null,我怀疑但无法确认 FacesContext 在 CdiUtils:213 上为 null.我怀疑这是由于同时拥有多个容器(Tomcat、CDI、Spring 和 JSF)造成的混淆.我确实喜欢 Spring Security、RestTemplate 和 JdbcTemplate,所以我有点不愿意放弃 Spring.这是我的 Push bean.我把所有的注释都扔给了它:

My debugger reveals that on CdiUtils:230 beanManager is null and I suspect but cannot confirm that FacesContext is null on CdiUtils:213. I suspect this is due to confusion from having multiple containers (Tomcat, CDI, Spring and JSF) at the same time. I do like Spring Security, RestTemplate, and JdbcTemplate, so I'm a little reluctant to give Spring up. Here is my Push bean. I threw every annotation at it I had:

@Component
@Scope("Application")
public class PushBean implements Serializable {

    private static final long serialVersionUID = -6558314691176100417L;

    @Inject
    @Push(channel = "facilitatorBroadcastMessages")
    private PushContext push;

    private String facilitatorBroadcastMessage;

    public void setFacilitatorBroadcastMessage(String message) {
        this.facilitatorBroadcastMessage = message;
    }

    public void broadcastFacilitatorMessage() {
        push.send(facilitatorBroadcastMessage);
    }
}

发送消息的 Facelet 代码:

Facelet code that sends the message:

<p:button value="Send Broadcast Message to All Users" onclick="PF('broadcastMessageDialog').show(); " />
<p:dialog id="broadcastMessageDialog" header="Facilitator Message" widgetVar="broadcastMessageDialog" height="500px">
    <p:inputText id="facilitatorBroadcastMessageInput" value="#{pushBean.facilitatorBroadcastMessage}" />
    <p:commandButton onclick="PF('broadcastMessageDialog').hide(); " value="Send" process="@parent" action="#{pushBean.broadcastFacilitatorMessage()}" />
</p:dialog>

JS websocket 监听器:

JS websocket listener:

function websocketListener(message, channel, event) {
    $("#facilitatorBroadcastMessage").innerHTML = message;
    PF('facilitatorBroadcastMessageDialog').show();
}

用于显示消息的 JSF websocket 标记和代码:

JSF websocket tag and code for displaying the message:

<f:websocket channel="facilitatorBroadcastMessages" onmessage="webSocketListener" />
<p:dialog id="facilitatorBroadcastMessageDialog" header="Facilitator Message" widgetVar="facilitatorBroadcastMessageDialog" height="500px">
    <p id="facilitatorBroadcastMessage"></p>
    <p:button onclick="PF('facilitatorBroadcastMessageDialog').hide(); " value="Got it, thanks!"/>
</p:dialog>

任何想法如何解决这个问题?

Any ideas how to fix this?

推荐答案

看看这个 http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html.您需要安装 Weld.

Look at this http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html. You need to install Weld.

你需要做这三个步骤:

  1. 将weld-servlet-shaded.jar 放到webapp 的/WEB-INF/lib 中.如果您使用 Maven,这是坐标:

<dependency>
      <groupId>org.jboss.weld.servlet</groupId>
      <artifactId>weld-servlet-shaded</artifactId>
      <version>3.0.3.Final</version>
    </dependency>

  1. 在 webapp 的 Web 内容中创建/META-INF/context.xml 文件,其中包含以下内容(或者,如果您已经有了,则只添加条目):

<Context>
    <Resource name="BeanManager" 
        auth="Container"
        type="javax.enterprise.inject.spi.BeanManager"
        factory="org.jboss.weld.resources.ManagerObjectFactory" />
   </Context>

这将在 Tomcat 的 JNDI 中注册 Weld 的 BeanManager 工厂.这不能由 Weld 以编程方式执行,因为 Tomcat 的 JNDI 是严格只读的.如果您的目标至少是 Mojarra 2.2.11 和/或 OmniFaces 2.4 或更新版本,则不需要此步骤.两者都可以在 ServletContext 中找到它.但是,可能还有其他库仍然希望在 JNDI 中找到 BeanManager,那么您最好为这些库保留此配置文件.

This will register Weld's BeanManager factory in Tomcat's JNDI. This cannot be performed programmatically by Weld because Tomcat's JNDI is strictly read-only. This step is not necessary if you're targeting at least Mojarra 2.2.11 and/or OmniFaces 2.4 or newer. Both are able to find it in ServletContext instead. However, there may be other libraries which still expect to find BeanManager in JNDI, you'd then best keep this configuration file anyway for those libraries.

  1. 创建一个(空)/WEB-INF/beans.xml 文件(不,不在/META-INF 中!这仅适用于内部 JAR 文件,例如 OmniFaces).

这篇关于Websocket CdiUtils NPE 使用 &lt;f:websocket/&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆