Springdoc打包WAR可运行,嵌入Wildfly31的EAR无法启动(JDK17)
问题
当前使用spring-core 6.1.5、springdoc-openapi-starter-webmvc-ui 2.5.0,将应用打包为WAR部署到基于JDK17运行的Wildfly31时,运行正常,可正常访问api-docs与swagger-ui.html;但打包为EAR时应用无法启动。两种包类路径完全一致,仅WAR的依赖存放在/lib目录,EAR的依赖存放在EAR包内,且WAR清单文件包含相同JAR包。报错如下:
Caused by: java.lang.NoClassDefFoundError: Failed to link org/springframework/web/servlet/support/AbstractDispatcherServletInitializer (Module "deployment.springdocweb-module-7.0.0-SNAPSHOT.ear.spring-webmvc-6.1.5.jar" from Service Module Loader): org/springframework/web/context/AbstractContextLoaderInitializer at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1095) 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@31.0.1.Final//org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.loadClassInfoSet(ServletContainerInitializerDeploymentProcessor.java:277) at org.wildfly.extension.undertow@31.0.1.Final//org.wildfly.extension.undertow.deployment.ServletContainerInitializerDeploymentProcessor.deploy(ServletContainerInitializerDeploymentProcessor.java:179) at org.jboss.as.server@23.0.3.Final//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:172) ... 8 more
注:正将原使用Springfox的REST模块升级为Springdoc,适配JDK17与Jakarta API,示例应用在Springboot与WAR环境下正常运行,EAR环境无法启动。
解决方案
- 统一Spring依赖存放位置:Wildfly的EAR类加载机制中,EAR/lib下的依赖对所有子模块全局可见,而WAR内部的依赖仅对当前WAR可见。
AbstractContextLoaderInitializer属于spring-web包,需确保spring-web-6.1.5.jar和spring-webmvc-6.1.5.jar一起放在EAR的/lib目录下,而非仅存在于WAR的WEB-INF/lib中。 - 排除Wildfly自带Spring模块:Wildfly可能内置旧版本Spring类库,与你引入的Spring 6.x冲突。在EAR的
jboss-deployment-structure.xml中添加排除配置:<jboss-deployment-structure> <deployment> <exclude-subsystems> <subsystem name="spring"/> </exclude-subsystems> <exclusions> <module name="org.springframework"/> </exclusions> </deployment> </jboss-deployment-structure> - 调整WAR类加载优先级:在EAR的
application.xml中,将WAR模块的类加载设置为优先使用EAR/lib下的依赖:<application> <module> <web> <web-uri>your-web-module.war</web-uri> <context-root>/your-root</context-root> </web> <module-classifier>EAR-LIB</module-classifier> </module> </application> - 验证依赖完整性:用
jar tf your-app.ear命令检查EAR/lib目录是否包含spring-web-6.1.5.jar,并确认该JAR内存在org/springframework/web/context/AbstractContextLoaderInitializer.class文件。
内容的提问来源于stack exchange,提问作者Alvin C
相关产品推荐
相关产品推荐

