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

WebSphere Liberty部署应用失败,Tomcat部署成功求助

问题分析与解决

错误信息翻译

启动应用ONNO时发生异常。异常消息为:com.ibm.ws.container.service.state.StateChangeException: org.jboss.weld.exceptions.DeploymentException: WELD-001414: Bean名称存在歧义。名称requestScope解析到两个bean:[生产者方法 [Map<String, Object>],限定符为[@RequestMap @Any @Named],声明为[[UnbackedAnnotatedMethod] @Produces @RequestMap @Named @FacesScoped public org.apache.myfaces.cdi.FacesArtifactProducer.getRequestMap()], com.sun.faces.cdi.RequestMapProducer@918359cd]

问题原因

WebSphere Liberty中同时加载了Apache MyFaces和**Mojarra(Sun Faces)**两个JSF实现的CDI生产者,两者都通过@Named("requestScope")暴露请求作用域的Map,导致Liberty默认的CDI容器Weld检测到bean名称冲突,触发部署失败。而Tomcat默认不会同时加载这两个JSF实现,因此未出现该问题。

解决办法

1. 统一项目JSF依赖

检查项目构建文件(pom.xml或build.gradle),确保只引入一个JSF实现:

  • 若使用MyFaces,移除所有Mojarra相关依赖;若使用Mojarra,移除所有MyFaces相关依赖。
  • Maven示例(移除Mojarra):
    <!-- 删除以下Mojarra依赖 -->
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <scope>provided</scope>
    </dependency>
    

2. 配置WebSphere Liberty排除多余JSF实现

若项目依赖无法修改,或Liberty自带了某个JSF实现,可通过server.xml配置排除不需要的实现:

  • 保留MyFaces、排除Mojarra:
    <featureManager>
        <feature>cdi-2.0</feature>
        <!-- 替换jsf特性为MyFaces特性 -->
        <feature>myFaces-2.3</feature>
    </featureManager>
    
  • 或让应用优先加载自身依赖,避免使用Liberty自带实现:
    <webApplication id="ONNO" location="ONNO.war" name="ONNO">
        <classloader delegation="parentLast"/>
    </webApplication>
    

3. 自定义CDI限定符规避冲突(不推荐)

若必须保留两个JSF实现,可通过自定义限定符为其中一个生产者指定唯一名称:

  • 创建自定义限定符注解:
    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
    public @interface CustomRequestMap {}
    
  • 重新定义生产者方法:
    @Produces
    @CustomRequestMap
    @Named("customRequestScope")
    @RequestScoped
    public Map<String, Object> getCustomRequestMap() {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
    }
    
  • 项目中使用时改用customRequestScope获取对应Map。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:26:10