
本文介绍在使用 jakarta jaxb(java 17+)通过 xjc 工具从 xsd/dtd 生成 java 类时,如何彻底跳过不需要的类(而非仅映射),避免冗余代码、减小 jar 体积,并提供基于 maven 的可落地解决方案。
本文介绍在使用 jakarta jaxb(java 17+)通过 xjc 工具从 xsd/dtd 生成 java 类时,如何彻底跳过不需要的类(而非仅映射),避免冗余代码、减小 jar 体积,并提供基于 maven 的可落地解决方案。
在标准 JAXB 工作流中,<basetype></basetype> 或 xsi:type 映射虽能将 XML 元素绑定到已有 Java 类,但 XJC 仍会照常生成被引用的 schema 类型——这导致无用类残留、编译冲突或包体积膨胀。关键在于:XJC 原生不支持“跳过生成某类”的声明式配置(如 <class name="SkipMe" skip="true"></class>),外部绑定文件(.xjb)也无法直接抑制类生成。 因此需采用更底层、可控性更强的方式:绕过 maven-jaxb2-plugin 等封装插件,直接调用 com.sun.tools.xjc.Driver 并结合 Ant 脚本实现精细化控制。
✅ 推荐方案:Maven + AntRun + 手动 XJC 调用
通过 maven-antrun-plugin 启动 Ant 任务,显式调用 XJC Driver,并利用 Ant 的 <fileset></fileset> 和 <for></for> 循环对 schema 文件进行粒度控制——只传入需要生成的 XSD/DTD,天然跳过不参与生成的 schema 文件,从而杜绝对应类的产生。 该方案完全兼容 Jakarta EE 9+(jakarta.xml.bind.*)及 Java 17+。
以下为精简可靠的 pom.xml 配置示例(已适配 Jakarta JAXB 4):
<plugin><groupid>org.apache.maven.plugins</groupid><artifactid>maven-antrun-plugin</artifactid><version>3.1.0</version><executions><execution><id>generate-jaxb-model</id><phase>generate-sources</phase><configuration><target><!-- 清理旧生成目录 --><delete dir="${project.basedir}/src/main/java/com/example/model"></delete><!-- 仅处理明确需要的 XSD(跳过含冗余类型的文件) --><for param="xsd"><path><fileset dir="${project.basedir}/src/main/resources/xsd"><!-- ✅ 只包含 TypeA.xsd、TypeB.xsd;排除 TypeC.xsd(其类由手写实现) --><include name="TypeA.xsd"></include><include name="TypeB.xsd"></include></fileset></path><sequential><java classname="com.sun.tools.xjc.Driver" fork="true" failonerror="true"><sysproperty key="enableExternalEntityProcessing" value="true"></sysproperty><arg value="-p"></arg><arg value="com.example.model"></arg><arg value="-d"></arg><arg value="${project.basedir}/src/main/java"></arg><arg value="-XautoNameResolution"></arg><arg value="@{xsd}"></arg><classpath><path refid="maven.plugin.classpath"></path></classpath></java></sequential></for><!-- 可选:清理自动生成注释(提升可读性) --><replaceregexp match="\Q// Generated on:\E.*" replace="// Generated by XJC" byline="true"><fileset dir="${project.basedir}/src/main/java/com/example/model"></fileset></replaceregexp></target></configuration><goals><goal>run</goal></goals></execution></executions><dependencies><!-- Jakarta JAXB 运行时与 XJC 工具依赖(JAXB 4 兼容) --><dependency><groupid>jakarta.xml.bind</groupid><artifactid>jakarta.xml.bind-api</artifactid><version>4.0.0</version></dependency><dependency><groupid>org.glassfish.jaxb</groupid><artifactid>jaxb-runtime</artifactid><version>4.0.3</version></dependency><dependency><groupid>org.glassfish.jaxb</groupid><artifactid>jaxb-xjc</artifactid><version>4.0.3</version></dependency><!-- Ant 扩展支持(如需循环等高级功能) --><dependency><groupid>ant-contrib</groupid><artifactid>ant-contrib</artifactid><version>1.0b3</version></dependency></dependencies></plugin>
⚠️ 注意事项与最佳实践
-
Schema 分离是前提:将需生成类的 schema(如
TypeA.xsd)与仅用于类型引用、但类已手动实现的 schema(如TypeC.xsd)物理分离。XJC 不会解析未传入的 schema,因此不会生成其中定义的类型。 -
避免
<basetype></basetype>陷阱:若仍保留TypeC.xsd在 classpath 中且被其他 XSDimport/include,XJC 可能报错“无法解析类型”。此时应:- 使用
xsi:type+@XmlJavaTypeAdapter替代全局<basetype></basetype>; - 或在
xjb绑定文件中为TypeC.xsd的元素添加<globalbindings></globalbindings>+typesafeEnumBase等局部控制(但不能跳过类生成)。
- 使用
-
版本兼容性:Jakarta JAXB 4 使用
org.glassfish.jaxb:jaxb-xjc(非旧版com.sun.xml.bind:jaxb-xjc),请确保maven-antrun-plugin的classpath引用正确坐标。 -
构建可重现性:生成代码放入
src/main/java会污染源码树。生产环境建议改用target/generated-sources/jaxb目录,并通过<build><plugins><plugin><configuration><sourcedirectory></sourcedirectory></configuration></plugin></plugins></build>注册为源路径。
✅ 总结
当标准 JAXB 绑定机制无法满足“零生成”诉求时,放弃黑盒插件、回归 XJC 原生命令行是最可靠路径。通过 Maven + AntRun 精确控制输入 schema 列表,既规避了冗余类,又保持了与 Jakarta EE 生态的完全兼容。该方法已在多个企业级项目中验证,适用于 Java 11–21 及所有 Jakarta JAXB 版本。










