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
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.
Schemagen and xjc shell scripts are only put into binary distribution in ./bin directory.
For build tools there are plugins out there (Maven / Gradle) which does invoke schemagen and xjc APIs, providing user with simple configuration.
Your attempt to invoke com.sun.tools.jxc.SchemaGeneratorFacade
manually is also correct, here is similar example for Maven. However you are probably putting 2.3.0 on module path, which has a split package problem. Putting on classpath will resolve the issue for 2.3.0. Next release of JAXB will be JPMS ready and have module descriptors declared. You can try the beta build (2.4.0-b180725.0644), here is a correct set of dependencies:
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId> <!--jaxb runtime-->
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-xjc</artifactId> <!--java generation-->
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-jxc</artifactId> <!--schema generation-->
</dependency>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With