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

迁移至Jakarta 9+JSF3后,模块化应用无法加载外部Jar中XHTML页面

解决方案:Jar中JSF资源/组件无法加载(Jakarta EE迁移)

1. 彻底替换Jar内配置文件的命名空间

检查Jar里的faces-config.xml、web-fragment.xml甚至taglib.xml,确保所有javax.*命名空间全替换为jakarta.*:

  • faces-config.xml需改为JSF 3的Jakarta规范:
<faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_3_0.xsd"
              version="3.0">
  • web-fragment.xml对应Jakarta EE 9版本:
<web-fragment xmlns="https://jakarta.ee/xml/ns/jakartaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-fragment_5_0.xsd"
              version="5.0">

注意:任何一个配置文件遗漏替换,都会导致JSF容器无法识别Jar内的资源和组件。

2. 修正Spring资源处理配置

确保Spring的资源处理器正确映射Jar中META-INF/resources下的内容:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/META-INF/resources/")
                .setCachePeriod(0);
    }
}

如果是传统Spring MVC,还要确认DispatcherServlet的映射不拦截*.xhtml请求——让FacesServlet专门处理JSF页面。

3. 验证复合组件的Taglib定义

针对<baseUtil:outputTextTruncate>这类组件,检查Jar内META-INF下的taglib.xml:

  • 替换命名空间为Jakarta规范,且页面中引用的命名空间URI必须和文件内的一致:
<taglib xmlns="https://jakarta.ee/xml/ns/jakartaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-jsf-taglib_3_0.xsd"
        version="3.0">
    <namespace>http://your-domain/baseUtil</namespace> <!-- 和页面xmlns:baseUtil的URI完全匹配 -->
    <tag>
        <name>outputTextTruncate</name>
        <component>
            <component-type>com.yourpackage.OutputTextTruncate</component-type>
            <renderer-type>com.yourpackage.OutputTextTruncateRenderer</renderer-type>
        </component>
    </tag>
</taglib>

4. 确认Jar的编译与依赖正确性

  • 重新编译外部Jar:把所有javax.faces.*、javax.servlet.*依赖替换为jakarta.faces.*、jakarta.servlet.*,旧的javax编译的Jar在Jakarta环境下会出现类加载冲突。
  • 确保Jar被正确引入:WAR包中要放到WEB-INF/lib,Spring Boot项目依赖范围设为compile或runtime,不要用provided。

5. 排查Tomcat与JSF版本冲突

Tomcat 10.x自带的JSF实现(MyFaces或Mojarra)要和项目依赖的JSF 3版本一致:

  • 如果用Mojarra,直接引入兼容依赖:
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>jakarta.faces</artifactId>
    <version>3.0.10</version>
</dependency>
  • 检查web.xml中FacesServlet的类路径是否改为Jakarta版本:
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

6. 类加载日志排查

开启Tomcat类加载日志,确认Jar内的配置文件是否被扫描:
在conf/logging.properties中添加:

org.apache.catalina.loader.WebappClassLoader.level = FINE
org.apache.catalina.loader.WebappClassLoader.useParentHandlers = false

启动后查看日志,验证faces-config.xml、taglib.xml是否被JSF容器识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:51:31