I have a question in regards to consuming a web service based on a third party wsdl file.
I've taken the given wsdl and generated the 120+ java files required. This process was done by using xjc. Within the Sping environment, I was able to successfully create a couple of JUnit tests by calling a couple of the exposed services.
But, in order to successfully test those services I had to add the #XmlRootElement annotation to the generated java files. Otherwise, I would encounter an error stating
"com.sun.istack.SAXException2: unable to marshal type
"com.beam.services.client.UserGetRequestData" as an element because it
is missing an #XmlRootElement annotation"
.
I've exhausted my search… I have no control as to how the wsdl file is created/structured. How can I go about generating the java files to ensure that the #XmlRootElement annotation is included or go about writing the client side code in way to avoid the error above?
Thank you.
If you really need the #XmlRootElement you could use simple binding mode if your type is used for only one element. The reason why JAXB does not include the annotation by default and how to use simple binding is explained here: https://community.oracle.com/blogs/kohsuke/2006/03/03/why-does-jaxb-put-xmlrootelement-sometimes-not-always:
your schema might be used by other schemas that XJC isn't compiling
right now
and
Such notion isn't defined in the spec, but as an experiment we have
such aggressive optimization mode in XJC, tentatively called
"simple-minded binding mode".
The sample seems to got lost when the moved the blog, but it looked like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="1.0" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionbindingprefixes="xjc">
<xs:annotation>
<xs:appinfo>
<jaxb:globalbindings>
<xjc:simple/>
</jaxb:globalbindings>
</xs:appinfo>
</xs:annotation>
<xs:element name="foo" type="bar"/>
<xs:complextype name="bar"/>
</xs:schema>
The other possibilty is to wrap it in a JAXBElement. The ObjectFactory should include a method for creating these wrapped objects.
If you are using mavem then check this link it worked for me.
Create Maven project. Below you can see the POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.zmeu</groupId>
<artifactId>zmeu-blog-maven-jaxb</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ZMEU Blog Maven JAXB</name>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.0</version>
<configuration>
<schemaDirectory>src/main/resources/schema</schemaDirectory>
<bindingDirectory>src/main/resources/schema</bindingDirectory>
<generatePackage>org.zmeu.blog.jaxb</generatePackage>
<strict>false</strict>
<extension>true</extension>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.2</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>0.6.2</version>
</plugin>
</plugins>
<args>
<arg>-Xannotate</arg>
<arg>-XtoString</arg>
</args>
</configuration>
<executions>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
<version>0.6.2</version>
</dependency>
</dependencies>
</project>
Write XML Schema (schema.xsd):
<?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="user" type="user" />
<xs:element name="userList" type="userList" />
<xs:complexType name="user">
<xs:all>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="name" type="xs:string" />
<xs:element name="registrationDate" type="xs:dateTime" />
</xs:all>
</xs:complexType>
<xs:complexType name="userList">
<xs:sequence>
<xs:element name="user" type="user" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Customize JAXB Bindings (binding.xjb):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:annox="http://annox.dev.java.net"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<jaxb:globalBindings>
<!-- Use java.util.Calendar instead of javax.xml.datatype.XMLGregorianCalendar for xs:dateTime -->
<jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime"
printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
<!-- Force all classes implements Serializable -->
<xjc:serializable uid="1" />
</jaxb:globalBindings>
<!-- Annotate the following classes with XmlRootElement -->
<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
<jaxb:bindings node="xs:complexType[#name='user']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="user" />
</annox:annotate>
</jaxb:bindings>
<jaxb:bindings node="xs:complexType[#name='userList']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="userList" />
</annox:annotate>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
Run the build using mvn clean install command. Build must be successful. Generated classes will be located in target/generated-sources/xjc directory. Below is a snippet from generated User class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "user", propOrder = {})
#XmlRootElement(name = "user")
public class User implements Serializable, ToString {
private final static long serialVersionUID = 1L;
protected Long id;
#XmlElement(required = true)
protected String name;
#XmlElement(required = true, type = String.class)
#XmlJavaTypeAdapter(Adapter1 .class)
#XmlSchemaType(name = "dateTime")
protected Calendar registrationDate;
}
You are done!
Related
I have xsd schema located in folder /src/main/resources, and i have pom.xml with jaxb plugin. I want to create classes from xsd file. However entering and starting "mvn compile" in terminale IntellijIdea, i get next exeption: "Caused by: java.lang.NoClassDefFoundError: javax/activation/MimeTypeParseException".
jaxb.xcd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.baeldung.com/springsoap/gen"
targetNamespace="http://www.baeldung.com/springsoap/gen" elementFormDefault="qualified">
<xs:element name="getCountryRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getCountryResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="country" type="tns:country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="country">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="population" type="xs:int"/>
<xs:element name="capital" type="xs:string"/>
<xs:element name="currency" type="tns:currency"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="currency">
<xs:restriction base="xs:string">
<xs:enumeration value="GBP"/>
<xs:enumeration value="EUR"/>
<xs:enumeration value="PLN"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SoapWebService</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>${project.basedir}/src/main/resources/</schemaDirectory>
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
</dependencies>
</project>
Tell my please decide this problem.
I have some control over some of my schemas so my question is a little different than the ones similar to this. I have three schemas, c.xsd imports b.xsd, b.xsd imports a.xsd. All three have different namespaces.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns="ANamespace" targetNamespace="ANamespace" version="1.0" jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0">
<xs:complexType name="ClassA">
<xs:sequence>
<xs:element name="classAFieldName" type="xs:string" minOccurs="0">
</xs:element>
</xs:sequence>
</xs:complexType>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns="BNamespace" targetNamespace="BNamespace" version="1.0" jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0">
<xs:import namespace="ANamespace" schemaLocation="a.xsd"/>
<xs:complexType name="ClassB">
<xs:sequence>
<xs:element name="classBFieldName" type="xs:string" minOccurs="0">
</xs:element>
</xs:sequence>
</xs:complexType>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns="CNamespace" targetNamespace="CNamespace" version="1.0" jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0">
<xs:import namespace="BNamespace" schemaLocation="b.xsd"/>
<xs:complexType name="ClassC">
<xs:sequence>
<xs:element name="classCFieldName" type="xs:string" minOccurs="0">
</xs:element>
</xs:sequence>
</xs:complexType>
Class A is generated twice, once in org.testing.common and once in org.testing.c and both of them both have the same namespace #XmlType(name = "ClassA", namespace = "ANamespace". However, Spring doesn't know which one to use. Do I really need ClassA generated twice?
Here is my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wfs.fi.stp</groupId>
<artifactId>testing</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>testing</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<versionRange>[0.13.1,)</versionRange>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<configurator>
<id>org.eclipselabs.m2e.jaxb2.connector.Jaxb2JavaProjectConfigurator</id>
</configurator>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.1</version>
<executions>
<execution>
<id>A</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources</schemaDirectory>
<schemaIncludes>
<include>a.xsd</include>
</schemaIncludes>
<bindingIncludes>
<include>a.xjb</include>
</bindingIncludes>
<generatePackage>org.testing.common</generatePackage>
<generateDirectory>${project.build.directory}/common_generated</generateDirectory>
<episode>true</episode>
<episodeFile>${project.build.directory}/common.episode</episodeFile>
<extension>true</extension>
<verbose>true</verbose>
<properties>
<property>
<name>javax.xml.accessExternalSchema</name>
<value>all</value>
</property>
<property>
<name>javax.xml.accessExternalDTD</name>
<value>all</value>
</property>
</properties>
<args>
<arg>-npa</arg>
</args>
<disableXmlSecurity>true</disableXmlSecurity>
<accessExternalSchema>all</accessExternalSchema>
<accessExternalDTD>all</accessExternalDTD>
</configuration>
</execution>
<execution>
<id>B</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources</schemaDirectory>
<schemaIncludes>
<include>b.xsd</include>
</schemaIncludes>
<generatePackage>org.testing.b</generatePackage>
<generateDirectory>${project.build.directory}/b_generated</generateDirectory>
<bindingIncludes>
<include>b.xjb</include>
</bindingIncludes>
<episode>true</episode>
<args>
<arg>-b</arg>
<arg>${project.build.directory}/common.episode</arg>
<arg>-npa</arg>
</args>
<episodeFile>${project.build.directory}/b.episode</episodeFile>
<extension>true</extension>
<verbose>true</verbose>
<disableXmlSecurity>true</disableXmlSecurity>
<accessExternalSchema>all</accessExternalSchema>
<accessExternalDTD>all</accessExternalDTD>
</configuration>
</execution>
<execution>
<id>C</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources</schemaDirectory>
<schemaIncludes>
<include>c.xsd</include>
</schemaIncludes>
<generatePackage>org.testing.c</generatePackage>
<generateDirectory>${project.build.directory}/c_generated</generateDirectory>
<bindingIncludes>
<include>c.xjb</include>
</bindingIncludes>
<args>
<arg>-b</arg>
<arg>${project.build.directory}/b.episode</arg>
<arg>-npa</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
</plugin>
</plugins>
<extension>true</extension>
<verbose>true</verbose>
<disableXmlSecurity>true</disableXmlSecurity>
<accessExternalSchema>all</accessExternalSchema>
<accessExternalDTD>all</accessExternalDTD>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run the generation goal once and specify your namespace to package mapping in your binding file instead of in the plugin config:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<jaxb:bindings schemaLocation="a.xsd">
<jaxb:schemaBindings>
<jaxb:package name="org.testing.common"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="b.xsd">
<jaxb:schemaBindings>
<jaxb:package name="org.testing.b"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="c.xsd">
<jaxb:schemaBindings>
<jaxb:package name="org.testing.c"/>
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
I have a problem with my JAXB-Generation. I have two XSDs (both in the same hierarchiy) which have a quite similiar schema-definition:
A.xsd
<xs:schema>
<xs:element name="A">
<xs:complexType>
<xs:sequence>
<xs:element name="CacheInfo">
<xs:complexType>
<xs:complexContent>
<xs:extension base="CacheType">
<xs:sequence ... />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element> <!--CacheInfo -->
</xs:sequence>
</xs:complexType>
</xs:element> <!-- A -->
<xs:complexType name="CacheType" ... />
<xs:complexType name="TimeType" ... />
</xs:schema>
B.xsd
<xs:schema>
<xs:element name="B">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element name="CacheInfo" type="CacheType">
</xs:element> <!--CacheInfo -->
<xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element> <!-- B -->
<xs:complexType name="CacheType" ... />
<xs:complexType name="TimeType" ... />
</xs:schema>
The structure of CacheType in this two XSDs is different. Its only the name the same.
My problem now is, that, when I try to generate the code I got this error:
[ERROR] file:A.xsd [95,38]
org.xml.sax.SAXParseException; systemId: file:A.xsd; lineNumber: 95; columnNumber: 38; 'CacheType' is already defined (same issue for TimeType)
When I remove one of the files, the generation is ok. I am not able to edit the XSDs, so I need a binding-file to rename the types for the two special cases:
<bindings schemaLocation="../xsd/A.xsd" node="//xs:complexType[#name='CacheType']">
<class name="ACacheType" />
</bindings>
<bindings schemaLocation="../xsd/B.xsd" node="//xs:complexType[#name='CacheType']">
<class name="BCacheType" />
</bindings>
But this doesnt work.
It also doesnt work, when I try to bind the types to a property (I am ending up in the same error):
<bindings schemaLocation="../xsd/A.xsd">
<bindings node="//xs:complexType[#name='CacheType']">
<property name="ACacheType" />
</bindings>
<bindings node=".//xs:complexType[#name='TimeType']">
<property name="ATimeType" />
</bindings>
</bindings>
<bindings schemaLocation="../xsd/B.xsd">
<bindings node="//xs:complexType[#name='CacheType']">
<property name="BCacheType" />
</bindings>
<bindings node=".//xs:complexType[#name='TimeType']">
<class name="BTimeType" />
</bindings>
</bindings>
Is there anything I dont see? Why I cant generate these two XSDs with these bindings?
To complete this, here is my pom.xml snippet:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>generate-htng-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
</plugin>
you need to define them at their own package
This will generate the same classes but in different packages, so it wont be a problem.
<jaxb:bindings schemaLocation="../xsd/A.xsd">
<jaxb:schemaBindings>
<jaxb:package name="packagea" />
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="../xsd/B.xsd">
<jaxb:schemaBindings>
<jaxb:package name="packageb" />
</jaxb:schemaBindings>
</jaxb:bindings>
i havent used this plugin. i use the following:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/xsd</schemaDirectory>
<bindingDirectory>src/main/resources/xsd</bindingDirectory>
<bindingIncludes>
<include>*.xjb</include>
</bindingIncludes>
<generateDirectory>${project.build.directory}/generated-sources</generateDirectory>
</configuration>
</execution>
</executions>
</plugin>
you can try with this too to see if you get any errors.
First, I'd ensure that the binding files are in the location expected by the jaxb2-maven-plugin. Specifying a package with a schemaBinding as mentioned by #Apostolos should have worked even without changing the plugin as I read the docs.
If the binding files are being applied, then one thing I notice is the bindings mentioned in the original question use a mix of property and class:
<bindings schemaLocation="../xsd/A.xsd">
<bindings node="//xs:complexType[#name='CacheType']">
<property name="ACacheType" /> <!-- property -->
</bindings>
<bindings node=".//xs:complexType[#name='TimeType']">
<property name="ATimeType" /> <!-- property -->
</bindings>
</bindings>
<bindings schemaLocation="../xsd/B.xsd">
<bindings node="//xs:complexType[#name='CacheType']">
<property name="BCacheType" /> <!-- property -->
</bindings>
<bindings node=".//xs:complexType[#name='TimeType']">
<class name="BTimeType" /> <!-- class -->
</bindings>
</bindings>
This document from Oracle has a section near the bottom on resolving conflicts. One example shows an element with name 'Class' which is a Java reserved word. They fix the conflict by specifying both property and class:
<jxb:bindings node="//xs:element[#name='Class']">
<jxb:class name="Clazz"/>
<jxb:property name="Clazz"/>
</jxb:bindings>
So I wonder, does it work if the binding is modified to specify both?
<bindings schemaLocation="../xsd/A.xsd">
<bindings node="//xs:complexType[#name='CacheType']">
<class name="ACacheType" />
<property name="ACacheType" />
</bindings>
... repeat for TimeType ....
</bindings>
I am trying to use the same generated class but in separate packages. So the structure should look something like this:
com.test.common
-commonType.java
com.test.A
-objectA.java
com.test.B
-objectB.java
But i keep getting this:
com.test.common
-commonType.java
com.test.A
-objectA.java
-commonType.java
com.test.B
-objectB.java
-commonType.java
My common.xsd looks like this:
<?xml version="1.0"?>
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com/magic/common"
xmlns="http://test.com/magic/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xs:complexType name="CommonType">
<xs:sequence>
<xs:element name="name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
the objectA.xsd looks like
<?xml version="1.0"?>
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com/magic/objectA"
xmlns:common="http://test.com/magic/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xs:complexType name="ObjectA">
<xs:sequence>
<xs:element name="size" type="xs:string" />
<xs:element name="commonA" type="common:CommonType" />
</xs:sequence>
</xs:complexType>
</xs:schema>
And objectB.xsd looks like:
<?xml version="1.0"?>
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://test.com/magic/objectB"
xmlns:common="http://test.com/magic/common"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xs:complexType name="ObjectB">
<xs:sequence>
<xs:element name="version" type="xs:string" />
<xs:element name="commonB" type="common:CommonType" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I have a common binding file common.xjb which looks like this:
<jxb:bindings schemaLocation="../xsd/common.xsd" node="/xsd:schema">
<jxb:schemaBindings>
<jxb:package name="com.test.common"/>
</jxb:schemaBindings>
</jxb:bindings>
And finally my maven job looks like this:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<args>
<arg>-Xequals</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.3</version>
</plugin>
</plugins>
<episode>true</episode>
<extension>true</extension>
<verbose>true</verbose>
<generateDirectory>src/main/java</generateDirectory>
</configuration>
<executions>
<execution>
<id>common</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>com.test.common</generatePackage>
<schemaIncludes>
<includeSchema>xsd/common.xsd</includeSchema>
</schemaIncludes>
</configuration>
</execution>
<execution>
<id>login</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>com.test.A</generatePackage>
<bindingIncludes>
<includeBinding>xjb/commons.xjb</includeBinding>
</bindingIncludes>
<schemaIncludes>
<includeSchema>xsd/objectA.xsd</includeSchema>
</schemaIncludes>
</configuration>
</execution>
<execution>
<id>alert</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generatePackage>com.test.B</generatePackage>
<bindingIncludes>
<includeBinding>xjb/commons.xjb</includeBinding>
</bindingIncludes>
<schemaIncludes>
<includeSchema>xsd/objectB.xsd</includeSchema>
</schemaIncludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
There is a part in the maven-jaxb2-plugin documentation dedicated specifically to the separate schema compilation. But you can also achieve your goal with usual XJC bindings.
Do not use generatePackage in the plugin config, use jaxb:package in bindings, ex.:
<jaxb:schemaBindings>
<jaxb:package name="generatePackage"/>
</jaxb:schemaBindings>
Use <jaxb:class ref="com.test.common.CommonType"/> on commonType in xjb/commons.xjb.
SO Disclaimer: I'm the author of the maven-jaxb2-plugin.
You can use the -episode extension in the JAXB XJC to handle this use case:
XJC call for common.xsd
xjc -d out -episode common.episode common.xsd
XJC call for objectA.xsd
The episode file produced from the first step is really a JAXB external bindings file that contains links between schema types and existing classes. This prevents XJC from regenerating these classes.
xjc -d out objectA.xsd -extension -b common.episode
For a Detailed Example
Can Castor handle class generation from multiple XSDs importing from a base XSD?
I'm exporting my mapping (hbm.xml) to pojo classes using ant task.
It generates the POJO files in the mapped directory. But the Classes miss the Package statement. It simply creates all files in default package
// default package
// Generated Aug 23, 2012 12:34:40 PM by Hibernate Tools 3.2.2.GA
Here is my ant build file for the task.
<project name="Hibernate Tools for Ant - hbm2java" default="gensrc">
<path id="tools">
<path location="lib/hibernate-tools-3.2.3.GA.jar"/>
<path location="lib/hibernate3.6.10.jar"/>
<path location="lib/freemarker-2.3.8.jar"/>
<path location="lib/hsqldb-2.2.4.jar"/>
<path location="lib/commons-logging.jar"/>
<path location="lib/dom4j-1.6.1.jar"/>
<path location="lib/slf4j-api-1.6.1.jar"/>
<path location="lib/hibernate-jpa-2.0-api-1.0.1.Final.jar"/>
</path>
<taskdef name="gen-src" classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="tools"/>
<target name="gensrc">
<gen-src destdir="src/main/java">
<configuration
configurationfile="src/main/resources/hibernate.cfg.xml">
<fileset dir="src/main/java/com/kee/example/domain/maps">
<include name="Event.hbm.xml"/>
</fileset>
</configuration>
<hbm2java destdir="src/main/java/com/kee/example/domain"/>
</gen-src>
</target>
</project>
the default Pojo.ftl (inside hibernate-tools.jar) has the declaration as below
${pojo.getPackageDeclaration()}
// Generated ${date} by Hibernate Tools ${version}
what should i be changing in order to have correct package declaration in the generated POJO.
Update:
Here is my Mapping file
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.kee.example.domain">
<meta attribute="generated-class">EventBase</meta>
<meta attribute="implement-equals">true</meta>
<meta attribute="scope-field">protected</meta>
<class name="com.kee.example.domain.Event" table="event">
<id name="id" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="eventDate" type="timestamp"/>
<property name="eventString" type="java.lang.String"/>
</class>
</hibernate-mapping>
I was getting the same problem in maven and not sure about the reason but it was resolved once I started using annotationconfiguration instead of jdbcconfiguration.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<components>
<component>
<name>hbm2ddl</name>
<implementation>annotationconfiguration</implementation>
<outputDirectory>${db.src.dir}</outputDirectory>
</component>
<component>
<name>hbm2java</name>
<implementation>annotationconfiguration</implementation>
<outputDirectory>src/main/java</outputDirectory>
</component>
</components>
<componentProperties>
<drop>true</drop>
<create>true</create>
<export>false</export>
<format>true</format>
<jdk5>true</jdk5>
<ejb3>true</ejb3>
<outputfilename>${ddl.file}</outputfilename>
<templatepath>src/main/resources/hibernate-template</templatepath>
<delimiter>;</delimiter>
<configurationfile>src/main/resources/hibernate.cfg.xml</configurationfile>
</componentProperties>
</configuration>
<dependencies>
<dependency>
<groupId>${jdbc.groupId}</groupId>
<artifactId>${jdbc.artifactId}</artifactId>
<version>${jdbc.version}</version>
</dependency>
</dependencies>
</plugin>
I did not want the annotated pojo classes so I had commented codes in *.ftl files.