JSF 2.3 无法通过 Tomcat 9 支持 WebSocket

Posted

技术标签:

【中文标题】JSF 2.3 无法通过 Tomcat 9 支持 WebSocket【英文标题】:JSF 2.3 fails to support WebSocket with Tomcat 9 【发布时间】:2018-04-07 22:13:27 【问题描述】:

我尝试使用 JSF 2.3.3(Glassfish 实现)测试新的 WebSocket 功能。我使用 Tomcat 9.0.1 作为 Web 服务器并遵循本指南(https://javaserverfaces.github.io/whats-new-in-jsf23.html)

我创建了一个托管 bean:

@Named
@ApplicationScoped
public class Controller 

    @Inject @Push
    private PushContext cityChannel;

    public void send() 
        cityChannel.send("test");
    

更新了 index.xhtml:

<f:websocket channel="cityChannel"
            onmessage="function(message)alert(message)" />

并更新了 web.xml:

<context-param>
    <param-name>javax.faces.ENABLE_CDI_RESOLVER_CHAIN</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <param-name>javax.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
    <param-value>true</param-value>
</context-param>

不幸的是,Tomcat 无法加载应用程序并出现错误:

SEVERE [main] com.sun.faces.config.ConfigureListener.contextInitialized Critical error during deployment:
 javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/javax.faces.push/channel] : existing endpoint was [class com.sun.faces.push.WebsocketEndpoint] and new endpoint is [class com.sun.faces.push.WebsocketEndpoint]
        at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:169)

如果我删除上下文参数 javax.faces.ENABLE_WEBSOCKET_ENDPOINT 则 JSF 运行时会在我点击 index.xhtml 时引发错误:

Caused by: java.lang.IllegalStateException: f:websocket endpoint is not enabled. You need to set web.xml context param 'javax.faces.ENABLE_WEBSOCKET_ENDPOINT' with value 'true'.

请指教。

【问题讨论】:

大概见github.com/javaserverfaces/mojarra/issues/4305 @Sergey 你找到解决这个问题的方法了吗?如果启用 websocket,我在使用 jsf 2.3 和 primefaces(6.1, 6.2) 时遇到同样的问题 【参考方案1】:

javax.websocket.DeploymentException:多个端点可能不会部署到同一路径 [/javax.faces.push/channel]:现有端点是 [class com.sun.faces.push.WebsocketEndpoint] 和新端点是 [class com.sun.faces.push.WebsocketEndpoint] 在 org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:169) 我

当运行时类路径被多个 Mojarra 实现污染时,就会发生这种情况。例如,一个来自jsf-impl.jar 文件,另一个来自javax.faces.jar 文件。甚至可能有多个不同的版本。

您需要确保在运行时类路径中只有一个版本的库。这并不特别适用于 Mojarra,而是适用于每个基于 Java 的库。

Mojarra 的安装说明可以在其README 中找到。

【讨论】:

以上是关于JSF 2.3 无法通过 Tomcat 9 支持 WebSocket的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 JSF 2.2 中的 web.xml 解决 ViewExpiredException

在 Spring+Tomcat 上使用 JSF 2.2.9 会导致 java.lang.NoClassDefFoundError: javax/enterprise/context/spi/Conte

tomcat为什么要寻找JSF类?

如何使用 netbeans 8.2 在 Wildfly 13 中运行 jsf mojarra 2.3?

Tomcat 上的 Spring Security/JSF/Hibernate 意外会话劫持?

(RC 4.3.4)中的rich:fileUpload 组件在Apache Tomcat7 和JSF 2.2 上工作吗? :“无法读取请求序言”