For simplicity reasons I reuse the code presented in this article to demonstrate the necessary steps to generate a Jaxb Schema from a Java class stored inside a Jar-archive
The code consists of two classes - Employee and Address:
package base.package;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "employee")
public class Employee
{
@XmlAttribute
private int id;
private String name;
private double salary;
private String designation;
private Address address;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary = salary; }
public String getDesignation() { return designation; }
public void setDesignation(String designation) { this.designation = designation; }
public Address getAddress() { return address; }
public void setAddress(Address address) { this.address = address; }
}
and a referenced class:
package base.package;
public class Address
{
private String line1;
private String line2;
private String city;
private String state;
private long zipcode;
public String getLine1() { return line1; }
public void setLine1(String line1) { this.line1 = line1; }
public String getLine2() { return line2; }
public void setLine2(String line2) { this.line2 = line2; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getState() { return state; }
public void setState(String state) { this.state = state; }
public long getZipcode() { return zipcode; }
public void setZipcode(long zipcode) { this.zipcode = zipcode; }
}
This code is now compiled using the following command: javac -d bin src/base/package/*.java
. This will compile all source files located in src to the bin directory:
base-dir
|- src
| \- base
| \- package
| |- Employee.java
| \- Address.java
\- bin
\- base
\- package
|- Employee.class
\- Address.class
To get a proper Jar-archive for the compiled classes use: jar -cf test.jar -C bin/ .
This will generate a test.jar
archive with the following content:
test.jar
|- base
| \- package
| |- Employee.class
| \- Address.class
\- META-INF
\- MANIFEST.MF
You could now remove the bin directory and all of its content as all the files we need are stored within the archive and to prove that the schema is actually generated from the files inside the Jar archive.
As all preparations are finally done, the actual issue can be tackled - how to generate the schema from .class-files located in that test.jar archive:
Simply run this command: schemagen -cp test.jar base.package.Employee
and it should generate a schema definition similar to the snippet below:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="employee" type="employee"/>
<xs:complexType name="employee">
<xs:sequence>
<xs:element name="address" type="address" minOccurs="0"/>
<xs:element name="designation" type="xs:string" minOccurs="0"/>
<xs:element name="salary" type="xs:double"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="address">
<xs:sequence>
<xs:element name="city" type="xs:string" minOccurs="0"/>
<xs:element name="line1" type="xs:string" minOccurs="0"/>
<xs:element name="line2" type="xs:string" minOccurs="0"/>
<xs:element name="state" type="xs:string" minOccurs="0"/>
<xs:element name="zipcode" type="xs:long"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Hope this was simple enough to follow
Edit: It seems that the jaxb2-maven-plugin as well as the ant-task are not able to use class-files at all, so probably the simplest and easiest solution would be to provide a script file (.bat on windows; .sh on *nix/Mac) where you just invoke the command manually:
As I'm currently running on Windows 7 a script that automatically generates the schema into a schemas subdirectory of the project would look like this:
schemagen -cp path/to/jar/*.jar -d ./schemas/ package.ClassName
You can then simply invoke that script (which I have placed in a scripts
subdirectory of the project) using the maven exec-plugin which is bound to the generate-sources phase:
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution>
<id>Generate schemas from class files contained in a jar</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${basedir}/scripts/generate-sources.bat</executable>
</configuration>
</execution>
</executions>
</plugin>
The schemas should then get automatically generated on executing mvn generate-sources
or any later phase maven provides.
Edit: I've modified the script slightly as it is able to deal with wildcards, though you have to specify *.jar
instead of only *
- but I guess this should be fine enough, at least this saves you from manually typing the names of the Jar-files that contain the JAXB classes