Spring/JoinFaces WAR部署WildFly时无法访问CDI问题求助
解决Spring Boot + JoinFaces部署到WildFly 27时的"Unable to access CDI"异常
问题背景
使用Spring Boot 3.3.1、JoinFaces 5.3.1构建的WAR包,Maven构建正常,部署到Tomcat 10可正常运行,但部署到WildFly 27.0.1.Final时抛出java.lang.IllegalStateException: Unable to access CDI异常,核心异常栈如下:
Caused by: java.lang.IllegalStateException: Unable to access CDI at jakarta.enterprise.api//jakarta.enterprise.inject.spi.CDI.lambda$getCDIProvider$0(CDI.java:98) at java.base/java.util.Optional.orElseThrow(Optional.java:403) at jakarta.enterprise.api//jakarta.enterprise.inject.spi.CDI.getCDIProvider(CDI.java:98) at jakarta.enterprise.api//jakarta.enterprise.inject.spi.CDI.current(CDI.java:65)
解决方案
该异常是由于Spring Boot、JoinFaces与WildFly自带的CDI实现(Weld)之间的依赖冲突或类加载顺序问题导致的,可通过以下步骤解决:
1. 调整Maven依赖,避免冲突
修改pom.xml中的依赖配置:
- 将
jakarta.validation-api设置为providedscope,因为WildFly已自带该API:<dependency> <groupId>jakarta.validation</groupId> <artifactId>jakarta.validation-api</artifactId> <scope>provided</scope> </dependency> - 排除
primefaces-spring-boot-starter中的Weld Servlet依赖,避免与WildFly自带的Weld冲突:<dependency> <groupId>org.joinfaces</groupId> <artifactId>primefaces-spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-core</artifactId> </exclusion> </exclusions> </dependency>
2. 添加WildFly部署结构配置文件
在src/main/webapp/WEB-INF目录下创建jboss-deployment-structure.xml,用于控制WildFly的模块加载与排除:
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <exclude-subsystems> <subsystem name="weld" /> </exclude-subsystems> <exclusions> <module name="javax.enterprise.api" /> <module name="javax.validation.api" /> <module name="org.jboss.weld.core" /> <module name="org.jboss.weld.spi" /> </exclusions> <dependencies> <module name="javax.enterprise.api" export="true" /> <module name="javax.validation.api" export="true" /> </dependencies> </deployment> </jboss-deployment-structure>
3. 确保Spring Boot启动类正确配置
确认你的Spring Boot启动类继承了SpringBootServletInitializer,这是WAR包部署到外部容器的必要配置:
@SpringBootApplication public class SpringbootprimeApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringbootprimeApplication.class); } public static void main(String[] args) { SpringApplication.run(SpringbootprimeApplication.class, args); } }
4. 可选:添加空的beans.xml文件
如果上述步骤仍未解决问题,可在src/main/webapp/WEB-INF下添加一个空的beans.xml文件,明确CDI的bean发现模式:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd" version="4.0" bean-discovery-mode="annotated"> </beans>
验证
重新构建WAR包,部署到WildFly 27,检查服务器日志,确认部署成功。
内容的提问来源于stack exchange,提问作者Bouchaib Souhail
相关产品推荐
相关产品推荐

