使用Gradle+Apache CXF WSDLToJava生成代码编译失败:已引依赖仍缺Jakarta包
解决Gradle+Apache CXF WSDLToJava生成代码后Jakarta包找不到的问题
问题根源
你仅在自定义的wsdl2java配置中声明了Jakarta相关依赖,但这个配置仅用于运行WSDLToJava代码生成工具。编译生成的Java代码时,compileJava任务的类路径并未包含这些依赖,导致代码中导入的jakarta.xml.bind.annotation包无法被解析。
解决方案
1. 为编译任务添加Jakarta依赖
在dependencies块中,将Jakarta XML Binding的API和实现添加到项目的编译/运行时依赖中,确保compileJava任务能访问到这些包:
dependencies { // 编译生成代码需要的API implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0' // 运行时需要的实现 runtimeOnly 'com.sun.xml.bind:jaxb-impl:4.0.2' // 原有的wsdl2java配置依赖 wsdl2java 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0' wsdl2java 'com.sun.xml.bind:jaxb-ri:4.0.2' wsdl2java 'org.apache.cxf:cxf-tools-wsdlto-core:4.0.0' wsdl2java 'org.apache.cxf:cxf-tools-wsdlto-frontend-jaxws:4.0.0' wsdl2java 'org.apache.cxf:cxf-tools-wsdlto-databinding-jaxb:4.0.0' }
2. 简化wsdl2java依赖(可选)
com.sun.xml.bind:jaxb-ri:4.0.2已经包含了jaxb-xjc、jaxb-core、jaxb-impl等子模块,因此可以移除这些重复的依赖项,减少配置冗余。
完整修改后的build.gradle
plugins { id 'java-library' } configurations { wsdl2java } dependencies { // 编译生成代码所需的Jakarta API implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0' // 运行时所需的JAXB实现 runtimeOnly 'com.sun.xml.bind:jaxb-impl:4.0.2' // 代码生成工具所需的依赖 wsdl2java 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0' wsdl2java 'com.sun.xml.bind:jaxb-ri:4.0.2' wsdl2java 'org.apache.cxf:cxf-tools-wsdlto-core:4.0.0' wsdl2java 'org.apache.cxf:cxf-tools-wsdlto-frontend-jaxws:4.0.0' wsdl2java 'org.apache.cxf:cxf-tools-wsdlto-databinding-jaxb:4.0.0' } def allmyWsdl = task allmyWsdl { String[] wsdls = ["one", "two", "three"]; wsdls.each {name-> def thing = task "myWsdl${name}" (type: JavaExec) { inputs.files("${projectDir}/src/main/resources") outputs.dir("${projectDir}/out/generated-sources/cxf-ws") String wsdl = "${projectDir}/src/main/resources/wsdls/${name}.wsdl" String genSrcDir = "${projectDir}/out/generated-sources/cxf-ws" inputs.file wsdl outputs.dir genSrcDir classpath configurations.wsdl2java main "org.apache.cxf.tools.wsdlto.WSDLToJava" args '-client', '-impl', '-exsh', 'true', '-noAddressBinding', '-autoNameResolution', "-wsdlLocation", "classpath:wsdls/${name}.wsdl", '-p', "com.my.webservices.${name}", '-encoding', 'UTF-8', '-d', genSrcDir, wsdl final OutputStream baos = new ByteArrayOutputStream() errorOutput = new OutputStream() { void write(int b) {System.err.write(b); baos.write(b) } void flush() { System.err.flush(); baos.flush() } void close() { System.err.close(); baos.close() } } doLast { def str = baos.toString() if (str.contains('Usage : wsdl2java') || str.contains('WSDLToJava Error')) { throw new TaskExecutionException(tasks[name], new IOException('Apache CXF WSDLToJava has failed. Please see System.err output.')) } } } } } allmyWsdl.dependsOn(tasks.matching { task -> task.name.startsWith( 'myWsdl' ) } ) compileJava.dependsOn += allmyWsdl sourceSets.main.java.srcDirs += 'out/generated-sources/cxf-ws'
原理说明
wsdl2java配置:仅用于运行Apache CXF的代码生成工具,确保工具本身能正常执行生成代码。implementation/runtimeOnly:用于项目编译和运行时,为生成的Java代码提供依赖的Jakarta包,解决编译阶段的包找不到问题。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

