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

Jersey集成Bean Validation报错:无法初始化jakarta.el.ExpressionFactory

问题根因

你遇到的类不匹配异常是Jetty容器自带的EL实现与Jakarta EE 9+的命名空间不兼容导致的:

  • 你使用的Jersey 3.x、Hibernate Validator 7.x都属于Jakarta EE 9+技术栈,所有API包前缀从javax.*改为jakarta.*
  • 你使用的jetty-maven-plugin默认内嵌的Apache EL实现还是旧的javax.el命名空间版本,org.apache.el.ExpressionFactoryImpl实现的是javax.el.ExpressionFactory接口,和你依赖里的jakarta.el.ExpressionFactory完全是两个不同的类,因此SPI加载时抛出子类型不匹配错误。
    你本地单独调用ExpressionFactory.newInstance()能成功,是因为此时上下文类加载器是应用类加载器,会优先加载你依赖里的GlassFish EL实现;而Hibernate Validator初始化时使用的是Jetty提供的WebApp类加载器,默认优先加载容器自带的类,因此拿到了不兼容的Apache EL实现。

解决方案

方案1:绕开EL依赖(配置最简单,无需修改容器)

如果你的校验错误消息不需要用到EL表达式插值功能,可以直接配置Hibernate Validator使用不需要EL的ParameterMessageInterpolator:

  1. 新建自定义Validation配置类,注册为Jersey的Provider:
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
import jakarta.validation.Configuration;
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;

@Provider
public class ValidationConfig implements ContextResolver<ValidatorFactory> {

    private final ValidatorFactory validatorFactory;

    public ValidationConfig() {
        Configuration<?> config = Validation.byDefaultProvider().configure();
        // 替换为不需要EL的消息插值器
        config.messageInterpolator(new ParameterMessageInterpolator());
        this.validatorFactory = config.buildValidatorFactory();
    }

    @Override
    public ValidatorFactory getContext(Class<?> clazz) {
        return validatorFactory;
    }
}
  1. 确保该类在Jersey的包扫描路径下即可解决启动报错。

方案2:修复EL类冲突(保留EL插值功能)

如果需要用到EL表达式的校验消息,需要调整Jetty插件配置,使用兼容Jakarta命名空间的环境:

  1. 修改pom.xml中的jetty-maven-plugin配置,升级到11.x版本(对应Jakarta EE 9支持),同时配置优先加载应用依赖的类:
<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>11.0.15</version>
    <configuration>
        <webApp>
            <!-- 优先加载项目依赖的类,避免Jetty自带的旧EL覆盖 -->
            <parentLoaderPriority>false</parentLoaderPriority>
        </webApp>
    </configuration>
</plugin>
  1. 你依赖中已经引入的GlassFish EL实现org.glassfish:jakarta.el会被优先加载,即可解决SPI加载时的类不匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 22:15:04