You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WildFly 12.0.0.Final中JSF 2.3与f:websocket的类加载问题

解决WildFly 12部署EAR时PushContext的ClassNotFoundException问题

看起来你是想在MongoDB插入文档时,通过EJB推送消息到JSF页面的WebSocket,但部署时遇到了PushContext的类找不到异常。这个问题我之前处理过,主要是EJB模块无法访问JSF 2.3 API以及EJB环境中获取PushContext的方式不对导致的,下面给你一步步的解决方案:

1. 先明确问题根源

javax.faces.push.PushContext是JSF 2.3新增的API类,WildFly 12虽然自带了JSF 2.3(默认是Mojarra 2.3.x版本),但EJB模块的类加载器默认不会自动关联JSF API的依赖——因为JSF通常是和Web模块绑定的,EJB容器的类加载路径里没有这个类,所以部署时反射解析EJB类就会报错。

2. 给EJB模块添加JSF API依赖

如果用Maven管理项目

在EJB模块的pom.xml里添加JSF API的依赖,注意scope设为provided(因为WildFly已经自带了,不要把它打包到EJB jar里,避免类冲突):

<dependency>
    <groupId>javax.faces</groupId>
    <artifactId>javax.faces-api</artifactId>
    <version>2.3</version>
    <scope>provided</scope>
</dependency>

如果是传统非Maven项目

在EJB模块的META-INF/MANIFEST.MF里添加依赖声明,或者在EAR的META-INF/jboss-deployment-structure.xml中配置模块依赖:

<jboss-deployment-structure>
    <sub-deployment name="你的EJB模块名称.jar">
        <dependencies>
            <!-- 引入WildFly自带的JSF API模块 -->
            <module name="javax.faces.api" slot="main"/>
        </dependencies>
    </sub-deployment>
</jboss-deployment-structure>

3. 修正EJB中获取PushContext的方式

**注意:EJB中不能用FacesContext.getCurrentInstance()来获取PushContext!**因为FacesContext是和Web请求绑定的,EJB可能在后台异步执行,此时没有活跃的Web上下文,会导致FacesContext为null,而且这本来就不是EJB环境下的正确用法。

正确的做法是用PushContextFactory来获取PushContext:

import javax.ejb.Stateless;
import javax.faces.push.PushContext;
import javax.faces.push.PushContextFactory;

@Stateless
public class FoodsCosmeticsMedService {

    public void onMongoDocumentInserted(String message) {
        // 获取PushContextFactory实例
        PushContextFactory pushContextFactory = PushContextFactory.getInstance();
        // 获取全局的PushContext
        PushContext pushContext = pushContextFactory.getPushContext();
        
        // 如果你的WebSocket是指定了通道名(比如<f:websocket channel="dataUpdates"/>)
        // PushContext channelPushContext = pushContext.getChannel("dataUpdates");
        
        // 推送消息到前端
        pushContext.send(message);
    }
}

4. 验证WildFly的JSF版本配置

确保WildFly 12确实启用了JSF 2.3,检查standalone.xml(或domain.xml)里的jsf子系统配置:

<subsystem xmlns="urn:jboss:domain:jsf:1.0">
    <default-jsf-library>mojarra-2.3.4.SP01</default-jsf-library>
</subsystem>

如果配置的是旧版本(比如2.2),需要调整为WildFly自带的2.3版本库(具体版本号可以看WildFly的modules目录下的javax/faces/api模块)。

5. 避免类冲突

检查EJB模块和Web模块的打包内容,确保没有把JSF API的jar包(比如javax.faces-api-2.3.jar)打包到模块里——因为WildFly已经提供了这个类,重复打包会导致类加载冲突,反而引发更多问题。

按照上面的步骤调整后,重新打包EAR部署到WildFly 12,应该就能解决PushContext的ClassNotFoundException问题了,EJB也能正常推送消息到JSF的WebSocket页面。

内容的提问来源于stack exchange,提问作者NOTiFY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:26:01