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

WebSphere Liberty 24.0.0.5中Mojarra与MyFaces冲突问题求助

问题背景

在IBM WebSphere Liberty Server 24.0.0.5上运行JSF 2.3 + Spring MVC应用时,启动阶段抛出如下错误:

The MyFaces JSF Implementation is selected for SampleApp but a Sun RI ConfigureListener is also registered.

实际项目中使用的是Mojarra(GlassFish JSF实现),并未引入MyFaces相关依赖。

相关配置文件

server.xml

<server description="new server">
    <featureManager>
        <feature>jsf-2.3</feature>
        <feature>cdi-2.0</feature>
        <feature>jdbc-4.2</feature>
        <feature>servlet-4.0</feature>
        <feature>websocket-1.1</feature>
    </featureManager>

    <httpEndpoint httpPort="9081" httpsPort="9443" id="defaultHttpEndpoint"/>
                  
    <applicationManager autoExpand="true"/>

    <webApplication contextRoot="SampleApp" id="SampleApp"
        location="D:\workspace\SampleApp\target\SampleApp-0.0.1-SNAPSHOT.war" name="SampleApp">
        <classloader apiTypeVisibility="spec, ibm-api, third-party"/>
    </webApplication>
</server>

web.xml

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

<servlet>
    <servlet-name>FacesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

pom.xml 核心依赖

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.3.9</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-core</artifactId>
    <version>3.1.8.Final</version>
</dependency>

已执行的排查操作

  • 用mvn dependency:tree检查依赖树,未发现MyFaces相关依赖
  • 移除了WEB-INF/lib中的javax.faces-api-2.2.jar

但问题仍存在,同时伴随空指针异常:

Stack Dump = java.lang.NullPointerException
at com.sun.faces.config.InitFacesContext.cleanupInitMaps(InitFacesContext.java:312)
at com.sun.faces.config.InitFacesContext.<init>(InitFacesContext.java:116)
at com.sun.faces.config.FacesInitializer.onStartup(FacesInitializer.java:148)
at com.ibm.ws.webcontainer.webapp.WebApp.initializeServletContainerInitializers(WebApp.java:2577)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1052)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6722)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:484)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:479)
at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1208)
at com.ibm.ws.webcontainer.osgi.WebContainer.access$100(WebContainer.java:113)
at com.ibm.ws.webcontainer.osgi.WebContainer$3.run(WebContainer.java:996)
at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:280)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

问题
  1. 为何Liberty会检测到MyFaces,而我明确使用的是Mojarra?
  2. 是否可以强制Liberty仅使用Mojarra,忽略MyFaces?
  3. 应如何配置server.xml以避免JSF冲突?

解决方案

1. 问题原因

WebSphere Liberty自带的jsf-2.3特性默认采用MyFaces作为JSF实现。即使你在pom.xml中声明Mojarra为provided scope,Liberty启动时仍会优先加载内置的MyFaces。同时你在web.xml中手动注册了Mojarra的ConfigureListener,导致Liberty检测到两种不同JSF实现的初始化逻辑,触发冲突错误。

2. 强制使用Mojarra的可行性

完全可以强制Liberty使用Mojarra,核心思路是排除Liberty内置的MyFaces实现,让应用优先加载自身的Mojarra库。

3. server.xml及相关配置调整

步骤1:修改server.xml

移除jsf-2.3特性(避免加载内置MyFaces),并调整类加载器为parentLast(让应用优先使用自身打包的库):

<server description="new server">
    <featureManager>
        <!-- 移除jsf-2.3特性,避免内置MyFaces -->
        <feature>cdi-2.0</feature>
        <feature>jdbc-4.2</feature>
        <feature>servlet-4.0</feature>
        <feature>websocket-1.1</feature>
    </featureManager>

    <httpEndpoint httpPort="9081" httpsPort="9443" id="defaultHttpEndpoint"/>
                  
    <applicationManager autoExpand="true"/>

    <webApplication contextRoot="SampleApp" id="SampleApp"
        location="D:\workspace\SampleApp\target\SampleApp-0.0.1-SNAPSHOT.war" name="SampleApp">
        <!-- parentLast让应用库优先于容器库加载 -->
        <classloader apiTypeVisibility="spec, ibm-api, third-party" delegation="parentLast"/>
    </webApplication>
</server>

步骤2:调整pom.xml的Mojarra依赖

将Mojarra的scope从provided改为compile,让Mojarra库打包到war的WEB-INF/lib中:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.3.9</version>
    <!-- 改为compile,将Mojarra打包到应用中 -->
    <scope>compile</scope>
</dependency>

步骤3:修改web.xml

移除手动注册的ConfigureListener,因为Mojarra会自动初始化该监听器,手动注册会引发冲突:

<!-- 移除以下监听器配置 -->
<!-- <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener> -->

<servlet>
    <servlet-name>FacesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

原理说明

  • 移除jsf-2.3特性:彻底避免Liberty加载内置的MyFaces实现
  • parentLast类加载策略:让应用优先使用自身打包的Mojarra,而不是容器级的库
  • 移除手动监听器:防止Mojarra的自动初始化流程与手动注册的监听器冲突,同时消除Liberty对混合JSF实现的检测

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:37:06