Resolved: Generate XSD or WSDL jaxb classes into multiple packages via maven-jaxb2-plugin

assume your app consumes multiple XSD or WSDL files from different vendors. You might want to generate the jaxb binding classes into separately packages per vendor's schema files. in this post, I will tell you 2 ways to do so.

Use <generateDirectory>${project.build.directory}/generated-sources/xxx</generateDirectory>

add multiple executions with different configuration. for each execution, you have to specify different generateDirectory, or it won't work. the below is a sample in pom.xml.

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.14.0</version>
    <executions>
        <execution>
            <id>xxx-wsdl-generate</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <schemaLanguage>AUTODETECT</schemaLanguage>
                <generatePackage>com.xxx</generatePackage>
                <schemaDirectory>${project.basedir}/src/main/resources/xxx</schemaDirectory>
                <noFileHeader>true</noFileHeader>
                <schemaIncludes>
                    <include>*.wsdl</include>
                </schemaIncludes>
                <generateDirectory>${project.build.directory}/generated-sources/xxx</generateDirectory>
            </configuration>
        </execution>
        <execution>
            <id>yyy-wsdl-generate</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <schemaLanguage>AUTODETECT</schemaLanguage>
                <schemaDirectory>${project.basedir}/src/main/resources/yyy</schemaDirectory>
                <noFileHeader>true</noFileHeader>
                <schemaIncludes>
                    <include>*.wsdl</include>
                </schemaIncludes>
                <generateDirectory>${project.build.directory}/generated-sources/yyy</generateDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

use xjb binding files

A list of regular expression file search patterns to specify the binding files to be processed. Searching is based from the root of bindingDirectory.
If left undefined, then all *.xjb files in schemaDirectory will be processed. You can add below into <configuration></configuration> section.

    <bindingIncludes>
        <bindingInclude>*.xjb</bindingInclude>
    </bindingIncludes>

Here is a snippet of a xjb file.

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
  <jaxb:bindings
    schemaLocation="xxx.xsd"
    node="/xs:schema">
    <jaxb:schemaBindings>
      <jaxb:package name="com.xxx"/>
    </jaxb:schemaBindings>
  </jaxb:bindings>
  <jaxb:bindings
    schemaLocation="yyy.xsd"
    node="/xs:schema">
    <jaxb:schemaBindings>
      <jaxb:package name="com.yyy"/>
    </jaxb:schemaBindings>
  </jaxb:bindings>
  <jaxb:bindings
    schemaLocation="zzz.wsdl"
    node="(//xs:schema)[1]">
    <jaxb:schemaBindings>
      <jaxb:package name="com.zzz.first"/>
    </jaxb:schemaBindings>
  </jaxb:bindings>
  <jaxb:bindings
    schemaLocation="zzz.wsdl"
    node="(//xs:schema)[2]">
    <jaxb:schemaBindings>
      <jaxb:package name="com.zzz.second"/>
    </jaxb:schemaBindings>
  </jaxb:bindings>
</jaxb:bindings>

common XJC Errors

you might encounter the below issues while xjc try to generate the jaxb binding classes from your schema files, to name a few in below:

Two declarations cause a collision in the ObjectFactory class

unable to honor class customization

A class/interface with the same name is already in use. Use a class customization to resolve this conflict.

In my opinion, the root cause is package conflict. Please check the error logs and it will report to you in detail which line in which schema caused the errors. Find the line in your schema and figure out the xpath for that node. Then set package to a different one should always fix the issue for your case.

You might noticed, in the above xjb sample, for zzz.wsdl, I set the package name to different values for two different nodes. in the zzz.wsdl, it has two xs:schema nodes, both of them has a same class which cause conflicts.  so I use node="(//xs:schema)[1]" to find the first xs:schema node and set its package  to zzz.first.

  <jaxb:bindings
    schemaLocation="zzz.wsdl"
    node="(//xs:schema)[1]">
    <jaxb:schemaBindings>
      <jaxb:package name="com.zzz.first"/>
    </jaxb:schemaBindings>
  </jaxb:bindings>
  <jaxb:bindings
    schemaLocation="zzz.wsdl"
    node="(//xs:schema)[2]">
    <jaxb:schemaBindings>
      <jaxb:package name="com.zzz.second"/>
    </jaxb:schemaBindings>
  </jaxb:bindings>

No comments:

Post a Comment

fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...