Spring6部署WildFly30时加载javax类引发NoClassDefFoundError
问题描述
承接JBoss 4.2.3升级到WildFly 30的部署问题,当前Spring 6项目抛出与javax相关的NoClassDefFoundError异常:
11:51:28,760 WARN [org.jboss.modules.define] (MSC service thread 1-2) Failed to define class org.springframework.web.servlet.tags.form.AbstractHtmlElementTag in Module "deployment.{my WAR name}.war" from Service Module Loader: java.lang.NoClassDefFoundError: Failed to link org/springframework/web/servlet/tags/form/AbstractHtmlElementTag (Module "deployment.{my WAR name}.war" from Service Module Loader): javax/servlet/jsp/tagext/DynamicAttributes at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1090) at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:351) at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:482) at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:276) at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:79) at org.jboss.modules.Module.loadModuleClass(Module.java:765) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:192) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1090) at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:351) at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:482) at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:276) at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:79) at org.jboss.modules.Module.loadModuleClass(Module.java:765) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:192) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:467) at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.utils.ClassLoadingUtils.loadClass(ClassLoadingUtils.java:26) at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.utils.ClassLoadingUtils.loadClass(ClassLoadingUtils.java:19) at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:67) at org.jboss.as.ee@30.0.0.Final//org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:60) at org.jboss.as.server@22.0.1.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:171) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1617) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1580) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1438) at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) at java.base/java.lang.Thread.run(Thread.java:833)
11:51:29,277 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC000001: Failed to start service jboss.deployment.unit."{my WAR name}.war".undertow-deployment.UndertowDeploymentInfoService: org.jboss.msc.service.StartException in service jboss.deployment.unit."{my WAR name}.war".undertow-deployment.UndertowDeploymentInfoService: Failed to start service at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1609) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1438) at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1363) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.lang.NoClassDefFoundError: Failed to link org/springframework/web/servlet/DispatcherServlet (Module "deployment.{my WAR name}.war" from Service Module Loader): Failed to link org/springframework/web/servlet/FrameworkServlet (Module "deployment.{my WAR name}.war" from Service Module Loader): Failed to link org/springframework/web/servlet/HttpServletBean (Module "deployment.{my WAR name}.war" from Service Module Loader): javax/servlet/http/HttpServlet at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1090) at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:351) at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:482) at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:276) at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:79) at org.jboss.modules.Module.loadModuleClass(Module.java:765) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:192) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1090) at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:351) at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:482) at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:276) at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:79) at org.jboss.modules.Module.loadModuleClass(Module.java:765) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:192) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1090) at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:351) at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:482) at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:276) at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:79) at org.jboss.modules.Module.loadModuleClass(Module.java:765) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:192) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) at org.wildfly.extension.undertow@30.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService.createServletConfig(UndertowDeploymentInfoService.java:634) at org.wildfly.extension.undertow@30.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService.start(UndertowDeploymentInfoService.java:270) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1617) at org.jboss.msc@1.5.2.Final//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1580) ... 6 more
已尝试替换所有javax引用为jakarta,且使用最新Spring库(6.1.3),但问题仍存在,需一份排查清单。
补充信息(2024-02-26)
- IDE:Eclipse 2023-12
- JDK:17
- Spring相关:Spring 6.1.3、Spring-security 6.2.1、Spring-boot 3.2.2
- Maven插件:compiler 3.11.0、WAR 3.4.0、failsafe 3.2.2
额外发现:
- 打包为EAR部署时无上述错误,但Web应用无法运行
- 打包为WAR部署到远程WildFly 30.0.0服务器时,部署无报错但访问无响应
排查清单
一、依赖检查
- 执行
mvn dependency:tree扫描依赖树,找出所有含javax.的依赖:- 排除WildFly提供的API(如Servlet API),其余必须替换为jakarta版本
- 重点排查第三方库:旧版数据库驱动、日志框架、工具类库是否仍依赖javax API
- 确认Spring Boot 3.x依赖管理生效:
- pom.xml需正确引入
spring-boot-starter-parent作为父项目,避免版本冲突导致javax依赖残留
- pom.xml需正确引入
- 将Servlet/JSP API标记为
provided:- WildFly 30自带Jakarta EE 10 API,需将项目中
servlet-api、jsp-api等依赖的scope设为provided,防止打包时带入javax版本API
- WildFly 30自带Jakarta EE 10 API,需将项目中
二、代码与配置检查
- 检查配置文件:
- 替换
web.xml、beans.xml中所有javax.servlet、javax.jsp命名空间为jakarta.servlet、jakarta.jsp - 检查自定义标签库、过滤器、监听器的类路径引用,确保使用jakarta包路径
- 替换
- 扫描项目源码:
- 全局搜索
javax.关键字,确认所有导入语句已替换为jakarta.(包括JSP页面的taglib引用) - 检查反射、
Class.forName等动态加载代码,是否仍引用javax类名
- 全局搜索
- 检查Spring配置:
- 确认DispatcherServlet配置使用正确的jakarta.servlet类路径
- 替换
@WebServlet、@Filter等注解为jakarta.servlet.annotation下的对应注解
三、打包与部署配置检查
- WAR/EAR打包配置:
- 检查Maven WAR插件配置,是否排除不必要的javax依赖
- 若用EAR部署,确认
application.xml中模块配置正确,Web模块类加载模式未引发类冲突
- WildFly配置调整:
- 检查
jboss-deployment-structure.xml:- 显式排除服务器中的javax遗留模块,或添加
jakarta.servlet.api等模块依赖
- 显式排除服务器中的javax遗留模块,或添加
- 确认WildFly 30的Jakarta EE 10兼容性模式已启用(默认启用,可检查
standalone.xml中ee-subsystem配置)
- 检查
四、额外验证步骤
- 检查WAR包内容:
- 解压WAR包,查看
WEB-INF/lib下是否存在含javax类的JAR文件 - 反编译
WEB-INF/classes下的class文件,确认是否仍引用javax包
- 解压WAR包,查看
- 本地调试:
- 用WildFly 30本地服务器启动项目,添加JVM参数
-verbose:class查看类加载路径,确认javax类是否被错误加载
- 用WildFly 30本地服务器启动项目,添加JVM参数
- 对比EAR与WAR部署差异:
- 检查EAR中是否有额外模块或配置导致类加载隔离,从而规避了NoClassDefFoundError但引发运行问题
- 确认WAR部署的上下文路径是否正确,访问无响应可能是DispatcherServlet未正确映射或请求路径配置错误
内容的提问来源于stack exchange,提问作者Patrick Siu
相关产品推荐
相关产品推荐

