cxf-xjc-plugin4.0.0+Java17:随机生成javax/jakarta注解致编译失败
cxf-xjc-plugin v4.0.0生成代码混用javax/jakarta导致编译失败的解决办法
问题现象
使用cxf-xjc-plugin v4.0.0生成XSD对应的Java代码时,出现两种不一致的生成结果:
- 部分代码引用
javax.xml.bind包,编译时抛出package javax.xml.bind.annotation does not exist错误; - 其余代码引用
jakarta.xml.bind包,文件头部标注由Eclipse Implementation of JAXB v3.0.2生成; - 前者无生成器注释,后者有明确的版本注释。
问题原因
cxf-xjc-plugin 4.x默认适配Jakarta EE规范(使用jakarta命名空间),但如果项目中存在旧的javax版本JAXB依赖,或者插件处理部分XSD时未正确加载Jakarta版本的生成器,就会出现混用命名空间的情况,导致编译失败。
解决步骤
1. 修改插件配置,强制使用Jakarta生成器
在插件配置中添加-Xjakarta参数,并明确指定Jakarta版本的jaxb-xjc依赖,确保所有XSD都使用同一生成器处理:
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-xjc-plugin</artifactId> <version>4.0.0</version> <!-- 强制引入Jakarta版本的JAXB XJC生成器 --> <dependencies> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-xjc</artifactId> <version>3.0.2</version> </dependency> </dependencies> <configuration> <extensions> <extension>org.apache.cxf.xjcplugins:cxf-xjc-dv:4.0.0</extension> </extensions> <!-- 强制生成Jakarta命名空间的代码 --> <args> <arg>-Xjakarta</arg> </args> </configuration> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <goals> <goal>xsdtojava</goal> </goals> <configuration> <sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot> <xsdOptions> <xsdOption> <xsd>src/main/resources/wadl/error.xsd</xsd> </xsdOption> <!-- 其他XSD配置保持不变 --> </xsdOptions> </configuration> </execution> </executions> </plugin>
2. 排查并排除旧的javax JAXB依赖
检查项目依赖树,确保没有引入javax.xml.bind:jaxb-api等旧版本JAXB依赖,若存在则通过<exclusions>排除:
<dependency> <groupId>第三方groupId</groupId> <artifactId>第三方artifactId</artifactId> <exclusions> <exclusion> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </exclusion> </exclusions> </dependency>
3. 清理并重新生成代码
执行以下Maven命令,清理旧的生成代码后重新生成:
mvn clean generate-sources
确保target目录下的旧生成文件被完全清除,避免残留代码干扰编译。
说明
添加-Xjakarta参数可以强制生成器输出Jakarta命名空间的代码,而明确指定jaxb-xjc版本则能保证所有XSD都使用同一版本的生成器处理,彻底解决代码生成不一致的问题。
内容的提问来源于stack exchange,提问作者Graham Leggett
相关产品推荐
相关产品推荐

