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

EAR项目中@FacesConverter无法注入EJB问题求助

EAR项目中@FacesConverter/@FacesValidator的@EJB注入及@PostConstruct失效问题解决方案

针对你遇到的EAR项目里@FacesConverter、@FacesValidator无法注入@EJB且@PostConstruct不生效的问题,以下是实际可落地的排查和解决步骤:

1. 修正CDI bean发现配置

EAR环境下,EJB模块的META-INF/beans.xml默认可能采用bean-discovery-mode="annotated"模式,这种模式下只有带有CDI原生注解(如@Named、@Singleton)的类才会被CDI容器管理。而@FacesConverter(managed=true)仅告知JSF将组件交给CDI,但不会触发CDI的bean发现逻辑。

解决方法:

  • 要么修改EJB模块的META-INF/beans.xml,将发现模式改为all:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
       bean-discovery-mode="all">
</beans>
  • 要么在@FacesConverter/@FacesValidator类上额外添加@Named注解,明确标记为CDI管理的bean:
@Named
@FacesConverter(managed = true, value = "demoConverter")
public class DemoConverter implements Converter<DemoEntity>, Serializable {
    @EJB
    DemoRemote bean;
    
    int i;
    
    @PostConstruct
    public void init() {i=42;}

    // 实现Converter接口方法
}

2. 确保EAR模块依赖正确

WEB模块需要能正确访问EJB模块的类,且CDI上下文能跨模块扫描:

  • 检查EAR的application.xml,确保WEB模块和EJB模块都被正确声明,且存在依赖关系:
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             version="8"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_8.xsd">
    <module>
        <ejb>your-ejb-module.jar</ejb>
    </module>
    <module>
        <web>
            <web-uri>your-web-module.war</web-uri>
            <context-root>/your-app</context-root>
        </web>
    </module>
</application>
  • 或者在WEB模块的MANIFEST.MF中添加对EJB模块的依赖:
Dependencies: your-ejb-module.jar

3. 调整类加载器配置

EAR环境下的类加载层次可能导致WEB模块无法访问EJB模块的CDI上下文:

  • Payara:在EAR的部署描述符(或Payara管理控制台)中开启delegate-first类加载模式,让WEB模块优先从父类加载器(EJB模块类加载器)获取类。
  • WildFly:修改jboss-deployment-structure.xml,确保WEB模块依赖EJB模块的类加载器:
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="deployment.your-ear-name.your-ejb-module.jar" export="true"/>
        </dependencies>
    </deployment>
</jboss-deployment-structure>

4. 替代方案:使用CDI生产者方法

如果以上方法无效,可以通过CDI生产者手动创建Converter/Validator实例并注入依赖:

  1. 移除原Converter类上的@FacesConverter和@EJB注解,添加setter方法:
public class DemoConverter implements Converter<DemoEntity>, Serializable {
    private DemoRemote bean;
    int i;

    public void setBean(DemoRemote bean) {
        this.bean = bean;
    }

    public void init() {i=42;}

    // 实现Converter接口方法
}
  1. 创建CDI生产者类:
@Named
public class ConverterProducer {
    @EJB
    private DemoRemote bean;

    @Produces
    @FacesConverter(value = "demoConverter")
    public Converter<DemoEntity> createDemoConverter() {
        DemoConverter converter = new DemoConverter();
        converter.setBean(bean);
        converter.init(); // 手动执行原@PostConstruct逻辑
        return converter;
    }
}

5. 验证CDI日志

调整CDI相关日志级别,查看容器是否正确发现并实例化了Converter/Validator:

  • Payara:开启javax.enterprise.inject和javax.enterprise.context的DEBUG级别日志,检查是否有Converter类的实例化记录。
  • WildFly:开启org.jboss.weld的DEBUG级别日志,排查CDI bean的扫描和实例化过程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:18:12