1

Because the schemagen tool from JAXB is not part of JDK 11 anymore, i wanted to setup a project using gradle which provides the functionality of the schemagen tool via the available ant task. Although, i got it running the ant task does not behave as expected. Especially the created schema does not match the source code annotations.

Furthermore, there is always an exception thrown, which i could not solve.

I use JDK 11, Gradle 5.4.1 and JAXB in version 2.3.2 on a windows 10 machine with a bash shell.

The project looks like this (A gradle java project):

Movie.java inside src/main/java/movie:

package movie;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Movie {

    @XmlElement
    public String name;

    @XmlAttribute
    public String genre;

}

build.gradle:

plugins {
    id 'java'
    id 'application'
}

repositories {
    jcenter()
}

configurations {
    schemagen
}

dependencies {
    implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.2'
    schemagen group: 'org.glassfish.jaxb', name: 'jaxb-jxc', version: '2.3.2'
}

def srcDir = file("src/main/java/movie")
def schemaDir = file("$buildDir/schema")

task schemagen {
    doLast {
        ant.taskdef(name: 'schemagen', classname: 'com.sun.tools.jxc.SchemaGenTask', classpath: configurations.schemagen.asPath)
        schemaDir.mkdirs()
        ant.schemagen(
            srcdir: srcDir,
            destdir: schemaDir,
            includeAntRuntime: false,
            debug: true,
            verbose: true)
    }
}

Now, when i run gradle schemagen --stacktrace, the following output is on the console:

> Task :schemagen FAILED
[ant:schemagen] anomalous package-info.java path: package-info.java
[ant:schemagen] [parsing started SimpleFileObject[...\src\main\java\movie\Movie.java]]
[ant:schemagen] [parsing completed 0ms]
[ant:schemagen] [parsing started SimpleFileObject[...\src\main\java\movie\package-info.java]]
[ant:schemagen] [parsing completed 0ms]
[ant:schemagen] [loading /modules/jdk.jconsole/module-info.class]
...many more
[ant:schemagen] [search path for source files: ...\src\main\java\movie]
[ant:schemagen] [search path for class files: C:\Program Files\Amazon Corretto\jdk11.0.3_7\lib\modules,...\build\schema]
[ant:schemagen] [loading /modules/java.base/java/lang/Object.class]
[ant:schemagen] [loading /modules/java.base/java/lang/String.class]
[ant:schemagen] [loading /modules/java.base/java/lang/Deprecated.class]
[ant:schemagen] [loading /modules/java.base/java/lang/annotation/Retention.class]
[ant:schemagen] [loading /modules/java.base/java/lang/annotation/RetentionPolicy.class]
[ant:schemagen] [loading /modules/java.base/java/lang/annotation/Target.class]
[ant:schemagen] [loading /modules/java.base/java/lang/annotation/ElementType.class]
[ant:schemagen] Round 1:
[ant:schemagen]         input files: {movie.Movie}
[ant:schemagen]         annotations: [XmlRootElement, XmlElement, XmlAttribute]
[ant:schemagen]         last round: false
[ant:schemagen] [loading /modules/java.base/java/lang/Character.class]
...many more
[ant:schemagen] [loading /modules/java.base/java/util/Collection.class]
[ant:schemagen] Processor com.sun.tools.jxc.ap.SchemaGenerator matches [XmlRootElement, XmlAttribute, XmlElement] and returns false.
[ant:schemagen] Round 2:
[ant:schemagen]         input files: {}
[ant:schemagen]         annotations: []
[ant:schemagen]         last round: true
[ant:schemagen] [total 297ms]

FAILURE: Build failed with an exception.

* Where:
Build file '...\build.gradle' line: 26

* What went wrong:
Execution failed for task ':schemagen'.
> schema generation failed

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':schemagen'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:151)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:148)
        at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:191)
        ...many more
Caused by: : schema generation failed
        at com.sun.tools.jxc.ApBasedTask.compile(ApBasedTask.java:142)
        at com.sun.tools.jxc.SchemaGenBase.compile(SchemaGenBase.java:228)
        at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:1130)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
        at jdk.internal.reflect.GeneratedMethodAccessor314.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        ...many more

(I shortened the output regading file system paths and unnecessary information)

Although the task fails, a schema is created, schema1.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="movie">
    <xs:sequence>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
      <xs:element name="genre" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

And here the @XmlAttribute-Annotation is ignored, the genre is simply included as an element.

I would have expected something like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="movie">
    <xs:sequence>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    <xs:extension base="xs:string">
        <xs:attribute name="genre" type="xs:boolean" use="required"/>
    </xs:extension>
  </xs:complexType>
</xs:schema>

Has anyone succeeded in setting up a project like this and got a valid schema from the schemagen ant task?

rlight
  • 70
  • 8

1 Answers1

0

For anyone looking for the solution to this. It is due to schemagen not having the required dependencies on the classpath.

In the schemagen dependency configuration add the required dependencies. For @XmlRootElement the dependency is bind-api.

Then set the classpath for schemagen using classpath { pathelement(path:) } as shown below.

    dependencies { 
    schemagen (
        'jakarta.xml.bind:jakarta.xml.bind-api:3.0.0-RC3',
        'jakarta.activation:jakarta.activation-api:2.0.0-RC3',
        'com.sun.xml.bind:jaxb-jxc:3.0.0-M4',
        'com.sun.xml.bind:jaxb-osgi:3.0.0-M4',
        'javax.xml.bind:jaxb-api:2.4.0-b180830.0359')
    }
    task schemagen {
        doLast {
            ant.taskdef(name: 'schemagen', classname: 'com.sun.tools.jxc.SchemaGenTask', classpath: configurations.schemagen.asPath)
            schemaDir.mkdirs()
            ant.schemagen(
                srcdir: srcDir,
                destdir: schemaDir,
                includeAntRuntime: false,
                debug: true,
                verbose: true){
                schema(file: "CustomSchema.xsd", namespace: "")
                classpath {
                    pathelement(path: configurations.schemagen.asPath)
                }
        }
    }
Shaz
  • 1
  • 1