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

Java 11+Maven+JAXB:生成并复用XSD映射类的实现咨询

问题解答

1. 需求是否可实现?

完全可以实现,你的需求是JAXB代码生成的典型场景,通过绑定文件(Bindings) + 片段(Episodes) 机制就能解决公共类型重复生成的问题,同时保证包结构与XSD目录结构对应。

2. 是否可通过Java 11+Maven结合现有插件实现?

可以实现。由于Java 11移除了JDK内置的JAXB模块,需要手动引入JAXB依赖,配合官方的jaxb-maven-plugin即可完成配置。


具体实现方案

第一步:编写绑定文件(bindings.xml)

在src/main/resources下创建绑定文件,指定每个XSD对应的Java包名:

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
    <!-- 公共类型对应根包 -->
    <jaxb:bindings schemaLocation="xsdfolder/commontypes.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="com.example.xsdfolder"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>
    <!-- dir1下的XSD对应子包 -->
    <jaxb:bindings schemaLocation="xsdfolder/dir1/file1.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="com.example.xsdfolder.dir1"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>
    <!-- dir2下的XSD对应子包 -->
    <jaxb:bindings schemaLocation="xsdfolder/dir2/file2.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="com.example.xsdfolder.dir2"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>
</jaxb:bindings>

第二步:配置Maven POM文件

核心思路是分三步执行代码生成:

  1. 先生成公共类型代码,并生成episode文件
  2. 生成dir1下的代码,引用公共类型的episode文件,避免重复生成
  3. 生成dir2下的代码,同样引用公共类型的episode文件

完整POM配置如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>jaxb-codegen-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <jaxb.version>2.3.8</jaxb.version>
    </properties>

    <!-- Java 11需手动引入JAXB依赖 -->
    <dependencies>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>${jaxb.version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>${jaxb.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>${jaxb.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 官方JAXB Maven插件 -->
            <plugin>
                <groupId>com.sun.xml.bind</groupId>
                <artifactId>jaxb-maven-plugin</artifactId>
                <version>${jaxb.version}</version>
                <executions>
                    <!-- 1. 生成公共类型代码和episode文件 -->
                    <execution>
                        <id>gen-common-types</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <schemaDirectory>${project.basedir}/src/main/resources/xsdfolder</schemaDirectory>
                            <schemaIncludes>
                                <include>commontypes.xsd</include>
                            </schemaIncludes>
                            <bindingDirectory>${project.basedir}/src/main/resources</bindingDirectory>
                            <bindingIncludes>
                                <include>bindings.xml</include>
                            </bindingIncludes>
                            <!-- 生成episode文件供后续模块引用 -->
                            <generateEpisode>true</generateEpisode>
                            <outputDirectory>${project.build.directory}/generated-sources/xjc</outputDirectory>
                        </configuration>
                    </execution>

                    <!-- 2. 生成dir1下的代码,引用公共类型的episode -->
                    <execution>
                        <id>gen-dir1-types</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <schemaDirectory>${project.basedir}/src/main/resources/xsdfolder/dir1</schemaDirectory>
                            <schemaIncludes>
                                <include>file1.xsd</include>
                            </schemaIncludes>
                            <bindingDirectory>${project.basedir}/src/main/resources</bindingDirectory>
                            <bindingIncludes>
                                <include>bindings.xml</include>
                            </bindingIncludes>
                            <!-- 引入公共类型的episode,避免重复生成 -->
                            <episodeFiles>
                                <episodeFile>${project.build.directory}/generated-sources/xjc/META-INF/sun-jaxb.episode</episodeFile>
                            </episodeFiles>
                            <outputDirectory>${project.build.directory}/generated-sources/xjc</outputDirectory>
                        </configuration>
                    </execution>

                    <!-- 3. 生成dir2下的代码,引用公共类型的episode -->
                    <execution>
                        <id>gen-dir2-types</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <schemaDirectory>${project.basedir}/src/main/resources/xsdfolder/dir2</schemaDirectory>
                            <schemaIncludes>
                                <include>file2.xsd</include>
                            </schemaIncludes>
                            <bindingDirectory>${project.basedir}/src/main/resources</bindingDirectory>
                            <bindingIncludes>
                                <include>bindings.xml</include>
                            </bindingIncludes>
                            <episodeFiles>
                                <episodeFile>${project.build.directory}/generated-sources/xjc/META-INF/sun-jaxb.episode</episodeFile>
                            </episodeFiles>
                            <outputDirectory>${project.build.directory}/generated-sources/xjc</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- 将生成的代码加入编译路径 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>add-generated-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.build.directory}/generated-sources/xjc</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

关键说明

  • 绑定文件:明确映射XSD到Java包,确保生成的类结构与XSD目录结构一致。
  • Episode机制:公共类型生成时生成的sun-jaxb.episode文件会记录已生成的类型信息,后续生成dir1/dir2代码时,JAXB会读取该文件,直接导入公共类型而不重复生成。
  • Java 11适配:通过手动引入JAXB相关依赖,配合适配Java 11的jaxb-maven-plugin版本(2.3.x及以上),解决Java 11移除JAXB模块的问题。

内容的提问来源于stack exchange,提问作者lux_piromani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 10:23:12