Quarkus搭配MyFaces JSF扩展原生编译后Bean Validation缺失错误如何解决
问题原因
该问题是GraalVM原生编译环境下,MyFaces JSF与Quarkus Hibernate Validator的加载逻辑不匹配导致的:
- Quarkus的
quarkus-hibernate-validator扩展会将校验工厂ValidatorFactory托管到CDI容器中,不会注册到JSF默认读取的SPI路径下 - MyFaces内置的
BeanValidator默认通过Java SPI机制加载校验工厂,GraalVM原生编译时会裁剪未被显式引用的SPI实现、反射元数据,导致原生环境下MyFaces无法找到校验工厂,抛出Bean Validation is not present错误 - JVM模式下SPI扫描可以正常识别到校验实现,因此运行无异常
解决方案
按优先级选择以下任意一种方案即可:
方案一:配置JSF使用CDI托管的校验工厂(最简便)
在项目src/main/resources/application.properties中添加如下配置:
quarkus.faces.context-parameters.javax.faces.validator.VALIDATOR_FACTORY=cdi
如果项目使用web.xml配置,也可以在META-INF/web.xml中添加上下文参数:
<context-param> <param-name>javax.faces.validator.VALIDATOR_FACTORY</param-name> <param-value>cdi</param-value> </context-param>
该配置会强制MyFaces从CDI容器中获取Quarkus已经初始化好的校验工厂,跳过SPI扫描逻辑。
方案二:升级Quarkus版本
你当前使用的Quarkus 2.1.4.Final版本较老,2.7及以上版本的Quarkus MyFaces扩展已经内置了校验逻辑的原生适配,升级到对应版本后无需额外配置即可正常使用Bean Validation功能。
方案三:手动暴露校验工厂
如果上述方案都不适用,可以添加一个CDI配置类,显式将Quarkus托管的校验工厂暴露给JSF上下文:
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.faces.annotation.FacesConfig; import javax.validation.ValidatorFactory; import javax.inject.Inject; @FacesConfig @ApplicationScoped public class ValidationConfig { @Inject ValidatorFactory validatorFactory; @Produces public ValidatorFactory produceValidatorFactory() { return validatorFactory; } }
内容的提问来源于stack exchange,提问作者Cristian Dolce
相关产品推荐
相关产品推荐

