Spring Boot部署JBoss后请求异常及Mojarra Injection SPI错误排查
Spring Boot部署JBoss后请求异常+Mojarra注入错误排查
问题现象
Spring Boot项目部署到JBoss服务器后,面板显示运行正常,但发送请求时返回404或“方法不被允许”。服务器日志中出现多条严重错误:
2022-11-29 12:59:17,796 SEVERE [javax.faces] (ServerService Thread Pool -- 564) Unable to call @PreDestroy annotated methods because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:02:44,170 SEVERE [javax.faces] (ServerService Thread Pool -- 585) Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:02:44,170 SEVERE [javax.faces] (ServerService Thread Pool -- 585) Unable to call @PreDestroy annotated methods because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:23:50,811 SEVERE [javax.faces] (ServerService Thread Pool -- 597) Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:23:50,812 SEVERE [javax.faces] (ServerService Thread Pool -- 597) Unable to call @PreDestroy annotated methods because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:26:04,650 SEVERE [javax.faces] (ServerService Thread Pool -- 613) Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:26:04,651 SEVERE [javax.faces] (ServerService Thread Pool -- 613) Unable to call @PreDestroy annotated methods because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:34:10,409 SEVERE [javax.faces] (ServerService Thread Pool -- 625) Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI? 2022-11-29 13:34:10,410 SEVERE [javax.faces] (ServerService Thread Pool -- 625) Unable to call @PreDestroy annotated methods because no InjectionProvider can be found. Does this container implement the Mojarra Injection SPI?
当前POM.xml配置
依赖部分
<properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <exclusions> <!-- <exclusion>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-starter-tomcat</artifactId>--> <!-- </exclusion>--> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- <exclusion>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-starter-tomcat</artifactId>--> <!-- </exclusion>--> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> </exclusions> </dependency> <!-- <dependency>--> <!-- <artifactId>tomcat-embed-websocket</artifactId>--> <!-- <groupId>org.apache.tomcat.embed</groupId>--> <!-- <scope>provided</scope>--> <!-- </dependency>--> <!-- <dependency>--> <!-- <groupId>javax.servlet</groupId>--> <!-- <artifactId>servlet-api</artifactId>--> <!-- <version>2.4</version>--> <!-- <scope>provided</scope>--> <!-- </dependency>--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> <exclusions> <!-- <exclusion>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-starter-tomcat</artifactId>--> <!-- </exclusion>--> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> <!-- <exclusion>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-starter-logging</artifactId>--> <!-- </exclusion>--> </exclusions> </dependency> <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <scope>runtime</scope> </dependency> </dependencies>
构建部分
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.project-lombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
解决方案
1. 调整POM配置适配JBoss
- 设置打包方式为WAR:在
<project>根节点添加<packaging>war</packaging> - 彻底排除内嵌Tomcat:在
spring-boot-starter-web和spring-boot-starter-security的exclusions中启用Tomcat排除,避免和JBoss容器冲突:<!-- 在spring-boot-starter-web中添加 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> <!-- 在spring-boot-starter-security中添加同样的排除 --> - 保留
spring-boot-starter-tomcat的provided依赖,确保编译时可用,运行时使用JBoss提供的容器。
2. 修改启动类适配Servlet容器
让Spring Boot启动类继承SpringBootServletInitializer,重写configure方法,确保JBoss能正确初始化Spring上下文:
@SpringBootApplication public class YourApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(YourApplication.class); } public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
3. 禁用JBoss的JSF模块
由于项目是Spring MVC而非JSF项目,JBoss自带的JSF模块会干扰Spring的DispatcherServlet,导致Mojarra注入错误。在src/main/webapp/WEB-INF下创建jboss-deployment-structure.xml:
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <exclude-subsystems> <subsystem name="jsf"/> </exclude-subsystems> <exclusions> <module name="javax.faces.api" slot="main"/> <module name="com.sun.jsf-impl" slot="main"/> </exclusions> </deployment> </jboss-deployment-structure>
4. 验证请求路径
确认请求路径包含JBoss部署的上下文路径(默认是WAR包名称),例如WAR包名为demo-app.war,则接口请求路径应为http://your-jboss-host:port/demo-app/api/xxx,避免因路径缺失导致404。
内容的提问来源于stack exchange,提问作者TechNewPy
相关产品推荐
相关产品推荐

