How do you invoke schemagen in Java 11?
Asked Answered
T

3

6

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
Trant answered 23/7, 2018 at 18:27 Comment(0)
W
3

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.

Waltner answered 24/7, 2018 at 15:15 Comment(0)
E
2

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>
Eligible answered 27/7, 2018 at 15:11 Comment(1)
I appreciate the answer. That indeed was the issue (2.3.0 on module path). I did look at the Gradle plugins and the only ones I found (that were documented) wrapped the xic tool, but not jxc... i.e. no support for schemagen. I have my code working with 2.4.0 beta.Trant
M
0

If trying to use the schemagen in the jaxb-ri download directly, note the JAXB_PATH in schemagen.bat is inconsistent with the mod directory in the jaxb-ri.zip file.

E.g. to use schemagen.bat:

  • As at now, download jaxb-ri-2.3.1.zip from https://maven.java.net/content/repositories/releases/com/sun/xml/bind/jaxb-ri/2.3.1/ (the 2.4.0-betas also had the mod/javax.activation-api.jar missing)

  • Use these steps to run schemagen.bat, setting JAXB_HOME as appropriate:

         set JAXB_HOME=C:\Java\jaxb-ri-2.3.1
         set CLASSPATH=%JAXB_HOME%/mod/relaxng-datatype.jar;%JAXB_HOME%/mod/javax.activation-api.jar
         %JAXB_HOME%\bin\schemagen.bat -cp myjar1.jar;myjar2.jar -d target com.company.ClassName1 com.company.ClassName2
    

(This was against JDK 11)

Mask answered 10/8, 2020 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.