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

JSF 2.3配置禁用CDI后仍报找不到CDI BeanManager如何解决

问题背景

正在将JSF 1.1项目升级至JSF 2.3,项目使用JSP作为视图技术,运行环境为Tomcat 9。
项目build.gradle中配置的JSF依赖如下:

api 'org.glassfish:javax.faces:2.3.9'

升级初期希望尽可能减少代码改动,保留原有faces-config.xml配置,让managed-bean继续由JSF管理而非交由CDI托管,同时暂时不启用PARTIAL_STATE_SAVING特性。
已在web.xml中添加如下上下文参数:

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

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

启动Tomcat时抛出如下错误:

javax.faces.FacesException: Unable to find CDI BeanManager
at com.sun.faces.el.ELUtils.tryAddCDIELResolver(ELUtils.java:312)
at com.sun.faces.el.ELUtils.buildFacesResolver(ELUtils.java:242)
at com.sun.faces.application.ApplicationAssociate.initializeELResolverChains(ApplicationAssociate.java:503)
at com.sun.faces.application.ApplicationImpl.performOneTimeELInitialization(ApplicationImpl.java:1405)
at com.sun.faces.application.ApplicationImpl.getELResolver(ApplicationImpl.java:529)

核心疑问:

  • 上述javax.faces.ENABLE_CDI_RESOLVER_CHAIN=false配置不生效的原因是什么
  • 如何在项目中彻底停用CDI,让Bean继续由JSF原生机制托管
  • 除了已配置的参数外,还需要补充什么配置

问题原因

javax.faces.ENABLE_CDI_RESOLVER_CHAIN=false本身就不能完全阻断JSF 2.3的CDI探测逻辑。这个参数的作用仅为控制是否将CDI的EL解析器加入JSF解析链,不会影响Mojarra 2.3启动时默认执行的CDI BeanManager探测流程。Tomcat作为轻量级Servlet容器本身没有内置CDI实现,探测不到BeanManager时就会直接抛出上述FacesException,和是否开启解析器链没有关系。


解决步骤

按以下配置调整即可彻底关闭CDI集成,完全保留原JSF托管Bean的运行逻辑,不需要改动现有业务代码:

  • 在web.xml中补充核心CDI禁用参数,这是之前缺失的关键配置:
<context-param>
    <param-name>javax.faces.DISABLE_CDI</param-name>
    <param-value>true</param-value>
</context-param>

该参数优先级最高,设置为true后JSF会直接跳过所有CDI相关的探测、集成、注解扫描逻辑,不会再尝试查找BeanManager,是JSF 2.3专门为不需要CDI的兼容场景预留的开关。

  • 修改faces-config.xml根节点,添加metadata-complete="true"属性,关闭JSF的类路径注解扫描,强制JSF完全按照XML配置加载托管Bean,和JSF 1.1的行为保持一致,参考配置:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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/web-facesconfig_2_3.xsd"
              version="2.3"
              metadata-complete="true">
    <!-- 原有managed-bean、导航规则等配置全部保留,不需要修改 -->
</faces-config>
  • 检查项目依赖,排除所有传递引入的CDI相关包(比如weld-core、cdi-api等),避免意外触发CDI加载逻辑。

  • 之前配置的两个上下文参数可以保留,不会产生冲突:

    • javax.faces.PARTIAL_STATE_SAVING=false:关闭部分状态保存,兼容JSP视图下的旧组件状态逻辑
    • javax.faces.ENABLE_CDI_RESOLVER_CHAIN=false:在CDI全局禁用的状态下这个参数不会生效,保留也无副作用。

配置完成后重启Tomcat即可正常启动,原有XML配置的managed-bean会和JSF 1.1时期一样由JSF原生机制托管,不需要额外接入CDI容器。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:27:34