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

