Grails应用2.x升级至4.0.8运行时出现JBossEntityResolver类找不到异常
异常根因定位
- 核心触发逻辑:堆栈显示报错来自JAX-WS客户端初始化阶段,类加载器加载到了老版本JBossWS实现的
ProviderImpl类,但该类依赖的org.jboss.util.xml.JBossEntityResolver属于已被废弃的老JBoss AS组件,在WildFly 11对应的官方客户端包中已被完全移除。 - 本地运行环境的类加载偏差:Grails 4基于Gradle构建的运行时(嵌入式Tomcat)类加载体系,不会自动识别项目根目录下手动放置的
lib目录Jar包,你手动放置的jbossall-client.jar本身是JBoss AS 4/5/6时代的遗留全量包,裁剪版本中根本不包含目标类,反而因为Jar包内置了老版本的JAX-WS SPI注册文件,被JDK的ServiceLoader机制优先选中,触发了不兼容的类加载分支。 - 生产与开发环境的机制差异:WildFly生产环境使用模块化类加载,会自动过滤应用包里的残留JBoss相关类,因此该问题仅在本地
grails run-app启动时暴露,不会在生产环境出现。
可落地解决步骤
- 清理历史遗留依赖
- 删除项目所有手动放置的
jbossall-client.jar及同目录下的其他老JBoss相关Jar包 - 全局排查
build.gradle中的依赖配置,排除所有版本低于2.0的org.jboss.ws、org.jboss.spec相关老依赖
- 删除项目所有手动放置的
- 引入适配WildFly 11的标准客户端依赖
- 移除手动放lib包的方式,在
build.gradle的dependencies块中添加官方匹配版本的依赖,同时排除所有可能引入老JBossWS实现的传递依赖:dependencies { // 适配WildFly 11的JAX-WS规范依赖 implementation 'org.jboss.spec.javax.xml.ws:jboss-jaxws-api_2.3_spec:2.0.0.Final' implementation 'org.wildfly.wildfly-client-config:wildfly-client-config:1.0.1.Final' } // 全局排除老JBossWS实现 configurations.all { exclude group: 'org.jboss.ws', module: 'jbossws-core' exclude group: 'org.jboss.ws', module: 'jbossws-common' }
- 移除手动放lib包的方式,在
- 强制指定JAX-WS SPI实现
- 为了避免类路径中残留的老Provider实现被
ServiceLoader优先加载,在应用启动类(grails-app/init/<项目名>Application.groovy)的main方法最开头添加系统属性配置,强制使用JDK内置的JAX-WS实现:static void main(String[] args) { // 跳过类路径中残留的老JAX-WS Provider,直接加载JDK默认实现 System.setProperty("javax.xml.ws.spi.Provider", "com.sun.xml.ws.spi.ProviderImpl") GrailsApp.run(Application, args) }
- 为了避免类路径中残留的老Provider实现被
- 验证依赖有效性
- 执行
gradle dependencies --configuration runtimeClasspath,确认运行时类路径中不存在org.jboss.util、老版本org.jboss.ws相关的依赖残留 - 启动应用后,在调用JAX-WS服务的代码行打断点,验证加载的JAX-WS Provider为指定的JDK内置实现,不会进入老的JBossWS代码分支
- 执行
补充说明:之前执行的
grails dependency-report无法识别lib目录Jar的问题,本质是Gradle构建体系下,非标准lib目录的Jar不会被纳入依赖管理范围,所有服务器适配依赖都应该通过Maven仓库引入匹配版本,而不是手动放置到项目目录中。
内容的提问来源于stack exchange,提问作者SAnVidIDeas
相关产品推荐
相关产品推荐

