Gradle中cxf-codegen-plugin结合jax-ws-catalog.xml离线生成代码失败
问题分析
错误提示Resource classpath:/local/xml.xsd was not found in the classloaders,核心原因是CXF的Wsdl2Java任务执行时,其classpath未包含项目的资源目录,导致无法解析classpath:/开头的资源路径。同时需确认本地XSD文件的实际位置是否与配置匹配。
解决步骤
1. 确认本地XSD文件路径正确性
确保xml.xsd文件放置在项目的src/main/resources/local/目录下,这样编译后资源会被打包到classpath的/local/xml.xsd路径,与catalog文件中的rewritePrefix="classpath:/local/xml.xsd"完全对应。
2. 给Wsdl2Java任务添加资源目录到classpath
修改build.gradle中的Wsdl2Java配置,显式将项目的resources目录加入到cxf-codegen的classpath中:
tasks.withType(Wsdl2Java).configureEach { toolOptions { markGenerated.set(true) outputDir.set(file("${buildDir}/generated")) addToMainSourceSet.set(true) wsdl.set(file("${projectDir}/src/main/resources/wsdl/myWsdl.wsdl")) catalog.set("${projectDir}/src/main/resources/META-INF/jax-ws-catalog.xml") // 关键:将主资源目录加入cxf codegen的classpath classpath.from sourceSets.main.resources.srcDirs } }
这一步让Wsdl2Java任务能够访问到src/main/resources下的所有本地资源。
3. 统一API依赖版本(可选但推荐)
注意到你同时引入了javax.xml.ws:jaxws-api和jakarta.xml.ws:jakarta.xml.ws-api,两者属于不同的API规范(Java EE vs Jakarta EE),可能引发类加载冲突。建议统一为Jakarta EE版本:
dependencies { // 替换javax为jakarta的API implementation "jakarta.xml.ws:jakarta.xml.ws-api:${jakartaWsApiVersion}" implementation "jakarta.jws:jakarta.jws-api:${jakartaJwsApiVersion}" // 其他依赖保持不变... }
4. 备选方案:使用文件系统路径(快速测试)
如果classpath方式仍有问题,可以临时将catalog中的rewritePrefix替换为绝对文件路径:
<?xml version="1.0"?> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> <rewriteURI uriStartString="http://www.w3.org/2001/xml.xsd" rewritePrefix="file:///你的项目绝对路径/src/main/resources/local/xml.xsd"/> </catalog>
注意替换为实际的项目绝对路径,这种方式适合快速验证,但不如classpath方式灵活。
验证
修改完成后,执行./gradlew clean wsdl2java,如果没有报错,说明本地XSD资源已被正确加载。
内容的提问来源于stack exchange,提问作者NewSheriff

