代码之家  ›  专栏  ›  技术社区  ›  snakedog

Websocket CdiUtils NPE使用

  •  2
  • snakedog  · 技术社区  · 6 年前

    该应用程序在TC7、Spring 3和JSF 2.2中运行良好,但我想添加JSF 2.3的推送功能,所以我升级到了TC 9.0.8、Spring 5.0.5和JSF 2.3.0,因为应用程序部署的升级很好,Spring安全性也很好(我可以登录),但随后我出现了以下错误:

    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,我怀疑但无法确认在CdiUtils:213上FacesContext为null。我怀疑这是由于同时使用多个容器(Tomcat、CDI、Spring和JSF)造成的混淆。我确实喜欢Spring安全性、RestTemplate和JdbcTemplate,所以我有点不愿意放弃Spring。这是我的推豆。我把我所有的注解都扔了进去:

    @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代码:

    <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侦听器:

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

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

    <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>
    

    有没有办法解决这个问题?

    1 回复  |  直到 6 年前
        1
  •  0
  •   bmlikota    6 年前

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

    您需要执行以下三个步骤:

    1. 带阴影的落焊servlet。webapp的/WEB-INF/lib中的jar。如果您使用的是Maven,这是坐标:

    <dependency>
          <groupId>org.jboss.weld.servlet</groupId>
          <artifactId>weld-servlet-shaded</artifactId>
          <version>3.0.3.Final</version>
        </dependency>
    1. 创建/META-INF/上下文。webapp的web内容中包含以下内容的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,那么您最好为这些库保留此配置文件。

    1. 创建(空)/WEB-INF/bean。xml文件(不,不在/META-INF中!它只用于内部JAR文件,如OmniFaces)。
    推荐文章