Generating jaxb classes from xsd using Gradle

This tutorial will show you how to generate Jaxb classes from Xsd file using Gradle. Generating jaxb classes from xsd using Gradle is not an easy task because Gradle does not have yet any ready-made plugin like Maven. So to generate java classes from xsd schema using Gradle we have to write an an Ant Task. The below example will show you how to do it.

Prerequisites

Eclipse

JDK 8 or 9

Have Gradle installed and configured

Required dependencies in Gradle’s build file

Now follow the below steps in order to complete the example.

Create Gradle project GradleXsdToJaxb in Eclipse

Put below shiporder.xsd file under src/main/resources/xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:tns="http://localhost/hello/hello-service" targetNamespace="http://localhost/hello/hello-service"
	elementFormDefault="qualified">

	<xs:element name='comment' type='xs:string' />
	<xs:element name='purchaseOrder' type='tns:PurchaseOrderType' />

	<xs:complexType name='USAddress'>
		<xs:annotation>
			<xs:documentation>
				Purchase order schema
			</xs:documentation>
		</xs:annotation>
		<xs:sequence>
			<xs:element name='name' type='xs:string' />
			<xs:element name='street' type='xs:string' />
			<xs:element name='city' type='xs:string' />
			<xs:element name='state' type='xs:string' />
			<xs:element name='zip' type='xs:decimal' />
		</xs:sequence>
		<xs:attribute name='country' type='xs:NMTOKEN' fixed='US' />
	</xs:complexType>

	<xs:simpleType name='SKU'>
		<xs:restriction base='xs:string'>
			<xs:pattern value='\d{3}\w{3}' />
		</xs:restriction>
	</xs:simpleType>

	<xs:complexType name='Items'>
		<xs:sequence>
			<xs:element name='item' minOccurs='0' maxOccurs='unbounded'>
				<xs:complexType>
					<xs:sequence>
						<xs:element name='productName' type='xs:string' />
						<xs:element name='quantity'>
							<xs:simpleType>
								<xs:restriction base='xs:positiveInteger'>
									<xs:minInclusive value='1' />
									<xs:maxExclusive value='100' />
								</xs:restriction>
							</xs:simpleType>
						</xs:element>
						<xs:element name='USPrice' type='xs:decimal' />
						<xs:element ref='tns:comment' />
						<xs:element name='shipDate' type='xs:date' minOccurs='0' />
					</xs:sequence>
					<xs:attribute name='partNum' type='tns:SKU' />
				</xs:complexType>
			</xs:element>
		</xs:sequence>
	</xs:complexType>

	<xs:complexType name='PurchaseOrderType'>
		<xs:sequence>
			<xs:element name='shipTo' type='tns:USAddress' />
			<xs:element name='billTo' type='tns:USAddress' />
			<xs:element ref='tns:comment' minOccurs='0' />
			<xs:element name='items' type='tns:Items' />
		</xs:sequence>
		<xs:attribute name='orderDate' type='xs:date' />
		<xs:attribute name='confirmDate' type='xs:date' use='required' />
	</xs:complexType>
</xs:schema>

Sample xsd could be found here https://msdn.microsoft.com/en-us/library/dd489271.aspx

build.gradle file

Gradle does not have a JAXB plugin (yet), it involves an ant task, which makes it a bit more complex than in maven.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
    }
}

apply plugin: 'java'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
	mavenCentral()
}

sourceSets.main.java.srcDirs "src/generated-sources/java"

configurations {
    jaxb
}

dependencies {
    jaxb (
		'com.sun.xml.bind:jaxb-xjc:2.2.7',
		'com.sun.xml.bind:jaxb-impl:2.2.7'
    )
}

task jaxb {
    System.setProperty('javax.xml.accessExternalSchema', 'all')
    def jaxbTargetDir = file("src/generated-sources/java")

    doLast {
        jaxbTargetDir.mkdirs()

        ant.taskdef(
			name: 'xjc',
			classname: 'com.sun.tools.xjc.XJCTask',
			classpath: configurations.jaxb.asPath
        )
        ant.jaxbTargetDir = jaxbTargetDir

        ant.xjc(
			destdir: '${jaxbTargetDir}',
			package: 'com.jeejava.jaxb',
			schema: 'src/main/resources/xsd/shiporder.xsd'
        )
    }
}

compileJava.dependsOn jaxb

Once you build the project you will find required Java classes have been generated under directory src/generated-sources/java.

If you face issue like “java.lang.NoClassDefFoundError: javax/activation/DataSource” in JDK 9 then add below line to gradle.properties file and build

org.gradle.jvmargs=--add-modules=java.xml.bind,java.activation

Now while refreshing project in Eclipse, if you face problem creating virtual machine then you can remove the above line from gradle.properties after build and refresh the project in Eclipse.

Thanks for reading.

Soumitra Roy Sarkar

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials Twitter Facebook  Google Plus Linkedin Or Email Me

Leave a Reply

Your email address will not be published. Required fields are marked *