javagradlejaxb2schemagenjava-11

How do you invoke schemagen in Java 11?


According to Oracle documentation the schemagen tool is removed from the JDK as part of JEP 320 (http://openjdk.java.net/jeps/320). That JEP points to Maven artifacts that now supply the missing tools. The coordinates of the artifacts are wrong in the JEP, updated coordinates are found in an answer to this question: Which artifacts should I use for JAXB RI in my Maven project?

What is missing however is how to invoke the tools. There are shell scripts pointed to in the JEP that are in the JAXB-RI Git repository. However those scripts remain undocumented and difficult to invoke. The build instructions in that git repo indicated it is built with a standard "mvn clean install", however that does not produce an output structure that matches the 'bin' folder used in the documentation here: https://javaee.github.io/jaxb-v2/doc/user-guide/ch04.html#tools-schemagen

Ideally I would like to run schemagen from Gradle, avoiding the shell scripts as they are not obtained from the maven dependency.

My current attempt, adapted from a working version that called the old schemagen.exe, looks like this:

(There is more in the 'real' build.gradle file to specify my application's dependencies, etc.)

configurations {
  schemagenTool
}
dependencies {
  schemagenTool "org.glassfish.jaxb:jaxb-jxc:${jaxbVersion}"
}
task schemaGen(type: Exec, dependsOn: [compileJava,configurations.schemaGenTool]) {
  workingDir projectDir
  executable 'java'

  doFirst {
    file('build/Schemas').mkdirs()
    args '--module-path', "${configurations.schemaGenTool.asPath}",
         '-m', 'jaxb.jxc/com.sun.tools.jxc.SchemaGeneratorFacade',
         // Note: automatic module name is NOT com.sun.tool.jxc
         // as documented
         // Args to schemagen (these worked for the schemagen.exe)
         '-d', 'build/Schemas',
         '-classpath', "${compileJava.destinationDir}${File.pathSeparator}${configurations.compile.asPath}",
         "src/main/java/path/to/my/ModelClass.java"
         //println "\nschemagen: ${args.join(' ')}\n"
  }

  doLast {
    // Above creates "build/Schemas/schema1.xsd" (despite printing a different path!)
    // Rename it
    def destFile = file('build/Schemas/model.xsd')
    destFile.delete()
    if (!file('build/Schemas/schema1.xsd').renameTo(destFile)) {
      throw new GradleException("Failed to write new build/Schemas/model.xsd")
    }
  }
}

However, that results in an error:

Error occurred during initialization of boot layer
java.lang.module.ResolutionException: Modules jaxb.runtime and jaxb.core export package com.sun.xml.bind.marshaller to module relaxngDatatype

Solution

  • The issue seems to be known with the jaxb-*:2.3.0 version - #jaxb-v2/issues/1168. Additionally, this would be resolved with a future release as marked in the known issues of jaxb running over java-9.

    You can resolve this following the comment -

    Please try 2.4.0-b180725.0644 - this is JPMS modularized RI working on JDKs with java.xml.bind module (9,10) and those without it (11-ea)

    or try downloading the binary distribution from the same link.