You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring非Boot应用迁移至Java17+Tomcat10后,Gradle中XJC任务抛出javax/xml/bind/JAXBException类找不到错误

Spring非Boot应用迁移至Java17+Tomcat10后,Gradle中XJC任务抛出javax/xml/bind/JAXBException类找不到错误

嘿,我完全理解你现在的困扰——把非Boot的Spring应用从Java8+Tomcat8升级到Java17+Tomcat10后,你已经把项目里的javax依赖换成了jakarta,但Gradle里的XJC代码生成任务还是炸了,报找不到javax/xml/bind/JAXBException的错。这问题本质上是你当前用的XJC工具还是基于旧的javax规范构建的,和现在Jakarta EE的生态完全不兼容,下面给你一步步解决的方案:

第一步:替换所有JAXB相关依赖为Jakarta适配版本

你之前用的jaxb:xmlbind、jaxb:impl、jaxb:xjc这些都是旧的javax体系下的依赖,必须换成Jakarta对应的版本。在Gradle的dependencies块里做如下替换:

dependencies {
    // 项目依赖的Jakarta JAXB包
    implementation 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.1'
    implementation 'com.sun.xml.bind:jaxb-impl:3.0.1'
    implementation 'jakarta.activation:jakarta.activation-api:2.0.1'
    
    // 给XJC任务单独配置的依赖组
    jaxb 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.1'
    jaxb 'com.sun.xml.bind:jaxb-impl:3.0.1'
    jaxb 'com.sun.xml.bind:jaxb-xjc:3.0.1'
    jaxb 'jakarta.activation:jakarta.activation-api:2.0.1'
}

注意:版本号选3.x及以上的,因为从3.0开始JAXB正式迁移到Jakarta命名空间,完全取代了旧的javax包。

第二步:调整Gradle的XJC任务配置

原来的XJC任务默认会走旧的javax类路径,现在必须让它使用我们刚刚配置的Jakarta依赖。这里有两种方式:

方式一:直接修改原生Exec任务(如果你不想用插件)

先定义一个专门的jaxb配置组,然后在XJC任务里指定类路径和主类:

// 定义专门给XJC用的配置组
configurations {
    jaxb
}

task xjcProcessPayment(type: Exec) {
    classpath = configurations.jaxb
    // 指定Jakarta版本的XJC主类
    mainClass = 'com.sun.tools.xjc.XJCFacade'
    args = [
        '-d', sourcesDir, // 生成代码的输出目录
        '-b', "${schema}/processPaymentBindings.jaxb", // JAXB绑定文件
        '-Xdefault-value',
        '-extension',
        "${schema}/provider/gpos/processPayment/*.xsd" // 目标XSD文件路径
    ]
    // 声明输出目录,让Gradle支持增量构建
    outputs.dir sourcesDir
}

方式二:用更省心的XJC Gradle插件(推荐)

使用org.unbroken-dome.xjc插件,它已经适配了Jakarta版本,配置更简洁。首先在settings.gradle里引入插件:

plugins {
    id 'org.unbroken-dome.xjc' version '2.0.0'
}

然后在build.gradle里配置XJC任务:

xjc {
    // 指定使用的Jakarta JAXB版本
    version = '3.0.1'
    // 关联我们定义的jaxb配置组
    xjcClasspath = configurations.jaxb
    // 全局默认参数
    defaultOptions {
        extension = true
        arg '-Xdefault-value'
    }
}

// 定义具体的代码生成任务
xjcGenerate {
    source = fileTree(dir: "${schema}/provider/gpos/processPayment", includes: ['*.xsd'])
    bindingFiles = file("${schema}/processPaymentBindings.jaxb")
    outputDir = file(sourcesDir)
}

关键原因说明

Java17已经完全移除了JDK自带的JAXB模块,而且Tomcat10全面切换到Jakarta EE规范(把javax.*包改成了jakarta.*)。你的XJC任务之前依赖的是旧的javax版工具,它在运行时会尝试加载javax.xml.bind下的类,但现在你的项目类路径里只有jakarta.xml.bind的类,自然就会抛出找不到类的错误——换成Jakarta版本的XJC工具后,它会正确加载jakarta.xml.bind下的类,问题就解决了。

备注:内容来源于stack exchange,提问作者WowBow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 12:43:10