Generating classes from XSD under Java 11 – the right way

Recently I was struggling with a task of generating model classes from XML schema (XSD) using Java 11 and Maven. I was really annoyed that jaxb2-maven-plugin was not updated for so long to cooperate properly with Java versions like 9, 10 or 11 (see my older posts: “jaxb2-maven-plugin 2.4 and Java 10” and “jaxb2-maven-plugin 2.4 and Java 11”). Obviously guys from MojoHaus Project don’t have enough capacity. Anyway I found a great alternative for jaxb2-maven-plugin which is fully ready for Java 11:

The CXF XJC Maven Plugin (cxf-xjc-plugin)

I will repeat: this is the only Maven plugin right now able to generate Java classes from XSD file under Java 11 right out of the box. No workarounds needed!

pom.xml

Let’s see how to use it:

<?xml version="1.0" encoding="UTF-8"?>
<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>...</groupId>
    <artifactId>...</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        ...
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.2</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.activation</groupId>
            <artifactId>jakarta.activation</artifactId>
            <version>1.2.1</version>
            <scope>runtime</scope>
        </dependency>        
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
                <configuration>
                    <argLine>--illegal-access=permit</argLine>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-xjc-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>xjc</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>xsdtojava</goal>
                        </goals>
                        <configuration>
                            <xsdOptions>
                                <xsdOption>
                                    <xsd>${basedir}/src/main/xsd/your.xsd</xsd>
                                    <packagename>your.package</packagename>
                                </xsdOption>
                            </xsdOptions>
                        </configuration>
                    </execution>
                </executions>                    
            </plugin>
        </plugins>
    </build>
</project>

It works great using Java 11 (openjdk 11.0.2 2019-01-15) and Maven 3.5.2! It’s a drop-in replacement for jaxb2-maven-plugin but it needs no workarounds for Java 11! Good bye jaxb2-maven-plugin, welcome cxf-xjc-plugin! 🙂

P.S.

Those used to jaxb2-maven-plugin should note one difference in configuration of cxf-xjc-plugin: paths to XSD files are relative to the build directory (target). Thus the easiest approach is to start XSD files paths with ${basedir}.

About krzysztoftomaszewski

I've got M.Sc. in software engineering. I graduated in 2005 at Institute of Computer Science, Warsaw University of Technology, Faculty of Electronics and Information Technology. I'm working on computer software design and engineering continuously since 2004.
This entry was posted in Java, XML and tagged , , , . Bookmark the permalink.

9 Responses to Generating classes from XSD under Java 11 – the right way

  1. vinis says:

    where I will declare ‘.xjb’ file

  2. vinis says:

    Thank you man Its working for me.

    org.apache.maven.plugins
    maven-surefire-plugin
    2.22.0


    the above plugin not required in my code

  3. Govind says:

    Hi, am getting

    Error inside systemOut parser (org.apache.cxf:cxf-xjc-plugin:3.3.0:xsdtojava:xjc:generate-sources)
    org.apache.maven.plugin.MojoExecutionException: Error inside systemOut parser
    at org.apache.cxf.maven_plugin.AbstractXSDToJavaMojo.execute(AbstractXSDToJavaMojo.java:289)
    at org.apache.cxf.maven_plugin.XSDToJavaMojo.execute(XSDToJavaMojo.java:41)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
    at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:333)
    at org.eclipse.m2e.core.internal.embedder.MavenImpl.lambda$7(MavenImpl.java:1380)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:177)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:112)
    at org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:1379)
    at org.eclipse.m2e.core.project.configurator.MojoExecutionBuildParticipant.build(MojoExecutionBuildParticipant.java:52)
    at org.eclipse.m2e.core.internal.builder.MavenBuilderImpl.build(MavenBuilderImpl.java:137)
    at org.eclipse.m2e.core.internal.builder.MavenBuilder$1.method(MavenBuilder.java:173)
    at org.eclipse.m2e.core.internal.builder.MavenBuilder$1.method(MavenBuilder.java:1)
    at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod$1$1.call(MavenBuilder.java:116)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:177)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:112)
    at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod$1.call(MavenBuilder.java:106)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.executeBare(MavenExecutionContext.java:177)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:151)
    at org.eclipse.m2e.core.internal.embedder.MavenExecutionContext.execute(MavenExecutionContext.java:99)
    at org.eclipse.m2e.core.internal.builder.MavenBuilder$BuildMethod.execute(MavenBuilder.java:87)
    at org.eclipse.m2e.core.internal.builder.MavenBuilder.build(MavenBuilder.java:201)
    at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:833)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
    at org.eclipse.core.internal.events.BuildManager._basicBuild(BuildManager.java:220)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:147)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:263)
    at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:316)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:319)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:371)
    at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:392)
    at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:154)
    at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:244)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
    Caused by: org.apache.maven.plugin.MojoExecutionException: Error inside systemOut parser
    at org.apache.cxf.maven_plugin.AbstractXSDToJavaMojo.runForked(AbstractXSDToJavaMojo.java:593)
    at org.apache.cxf.maven_plugin.AbstractXSDToJavaMojo.run(AbstractXSDToJavaMojo.java:374)
    at org.apache.cxf.maven_plugin.AbstractXSDToJavaMojo.execute(AbstractXSDToJavaMojo.java:276)
    … 33 more
    Caused by: org.codehaus.plexus.util.cli.CommandLineException: Error inside systemOut parser
    at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:222)
    at org.codehaus.plexus.util.cli.CommandLineUtils.executeCommandLine(CommandLineUtils.java:107)
    at org.apache.cxf.maven_plugin.AbstractXSDToJavaMojo.runForked(AbstractXSDToJavaMojo.java:590)
    … 35 more
    Caused by: java.lang.NullPointerException
    at org.sonatype.plexus.build.incremental.DefaultBuildContext.addMessage(DefaultBuildContext.java:113)
    at org.sonatype.plexus.build.incremental.ThreadBuildContext.addMessage(ThreadBuildContext.java:95)
    at org.apache.cxf.maven_plugin.AbstractXSDToJavaMojo$2.consumeLine(AbstractXSDToJavaMojo.java:561)

  4. Rafael Borges Dias Baptista says:

    I have 700+ xsd files to convert, divided in some subfolders. It doesn’t seems practical to list everyone manually in the pom.xml. I already tried the “xsdDir”, but it’s bugged. Any tips?

  5. mathieu147 says:

    But still, the generated classes import classes from the javax.xml package instead of jakarta.xml. Is there the expected behaviour or did I miss something?

    • This is just about generating Java classes that represent XML data structures according to the given schema. These generated classes have annotations which come from packages like `javax.xml.bind`. So yes, there are imports from such packages and this was expected. These classes are prepared to cooperate with JAXB.

      • mathieu147 says:

        Thanks for your answer. I used maven-antrun-plugin to search-and-replace “javax.xml.bind” with “jakarta.xml.bind”. Really not elegant but it works.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s