javamavenxsdjaxbmaven-jaxb2-plugin

jaxb2 Maven Plugin Fails to generate Java Packages with correct Imports or throws errors


I'm currently using the Maven jaxb2 plugin to generate POJOs from my XSDs. I have a few issues so far.

I have 1 parent XSD that imports another XSD that in turn imports 2 other XSDs. a.xsd -> b.xsd -> (c.xsd & d.xsd) In my POM file configuration for the plugin, I'm only including the top-most parent XSD (a.xsd).

Issue

Two of the imported XSDs have elements with the same name so initially, when I ran the plugin I received the error:

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

After a lot of googling and pouring over StackOverflow I came across the solution to use a custom binding file to handle renaming the offending classes/elements.

bindings.xjb
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb" version="2.0">

    <jaxb:bindings schemaLocation="./sets.xsd">
        <jaxb:schemaBindings>
            <jaxb:package name="foo.set"/>
        </jaxb:schemaBindings>
        <jaxb:bindings node="//xsd:complexType[@name='SomeType']">
            <jaxb:class name="SetsSomeType"/>
        </jaxb:bindings>
        <jaxb:bindings node="//xsd:complexType[@name='InfoType']">
            <jaxb:class name="SetsInfoType"/>
        </jaxb:bindings>
        <jaxb:bindings node="//xsd:complexType[@name='OpsType']">
            <jaxb:class name="SetsOpsType"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>
jaxb2 plugin configuration
<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>xsd-to-java</id>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                    </execution>
                </executions>

                <configuration>
                    <packageName>some.package.name.bindings</packageName>
                    <sources>
                        <source>src/main/xsd/package/messages.xsd</source>
                    </sources>
                    <xjbSources>
                        <xjbSource>src/main/xsd/package/bindings.xjb</xjbSource>
                    </xjbSources>
                    <xjbExcludeFilters>
                        <filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter">
                            <patterns>
                                <pattern>\.xsd</pattern>
                            </patterns>
                        </filter>
                    </xjbExcludeFilters>
                    <!--<arguments>
                        <argument>-XautoNameResolution</argument>
                    </arguments>-->

                </configuration>
            </plugin>

This resulted in the following error:

org.xml.sax.SAXParseException: not an external binding file. The root element must be {https://jakarta.ee/xml/ns/jaxb}bindings but it is {http://java.sun.com/xml/ns/jaxb}bindings

I cannot for the life of me understand why it's insisting on 'https://jakarta/ee/xml/ns/jaxb`!

Additionally, I also tried adding the -XautoNameResolution as an argument to my plugin configuration and got the same error.

I'm running the build from the Maven panel in IntelliJ too.

Any idea what I could be missing or have misconfigured?


Solution

  • The https://jakarta/ee/xml/ns/jaxb issue is that jaxb has moved from javax.xml.bind to jakarta.xml.bind in Java 17 (also SpringBoot 3 and Spring 6), breaking all sorts sorts of stuff. Same with javax.validation -> jakarta.validation.

    Anyway, take a look at this answer for how to fix