I'm using CXF and wsdl2java to autogenerate webservice classes.
Problem: somehow the webservice I want to connect to has duplicate names for some elements:
Two declarations cause a collision in the ObjectFactory class
The xsd is like:
<xs:schema targetNamespace="http://thenamespace">
<xs:complexType name="ViolatingName">
...
</xs:complexType>
<xs:element name="ViolatingName" nillable="true" type="tns:ViolatingName"/>
</xs:schema>
The xsd itself is imported inside the wsdl that is used to autogenerate the jaxb classes like this:
<wsdl:types>
<xsd:schema targetNamespace="http://imports">
<xsd:import schemaLocation="https://path.to.xsd" namespace="http://thenamespace" />
I'm trying to cover this using jaxb-bindings.xml:
<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"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.1">
<jaxb:bindings schemalocation="https://path.to.xsd" node="//xs:schema">
<jaxb:bindings node=".//xs:element[#name='ViolatingName']">
<jaxb:property name="ViolatingNameBinding" />
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
Result:
[ERROR] XPath evaluation of "//xs:schema" results in empty target node (org.apache.cxf:cxf-codegen-plugin:3.0.1:wsdl2java:generate-sources:generate-sources)
Why is the node wrong here? The xsd has a xs:schema tag, so why is this failing?
Interesting fact: when I use any xpath tool, download the XSD to my local machine an check the path, then //xs:schema/xs:element[#name='ViolatingName'] evaluates to the proper tag.
It turned out I have to apply a renaming/suffix on all xs:complexType elements like this:
<jaxb:bindings schemaLocation="https://path.to.xsd" node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:nameXmlTransform>
<jaxb:typeName suffix="Type" />
</jaxb:nameXmlTransform>
</jaxb:schemaBindings>
</jaxb:bindings>
Try jaxb:factoryMethod instead of jaxb:property.
<jaxb:bindings node=".//xs:element[#name='ViolatingName']">
<jaxb:factoryMethod name="ViolatingName1" />
</jaxb:bindings>
An example of binding using jaxb:factoryMethod.
Update:
This might help as well.
Property Binding Declarations
The binding declaration enables you to customize the binding of an XML schema element to its Java representation as a property. The scope of customization can either be at the definition level or component level depending upon where the binding declaration is specified.
The syntax for customizations is:
<property [ name = "propertyName"]
[ collectionType = "propertyCollectionType" ]
[ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ]
[ generateIsSetMethod = "true" | "false" | "1" | "0" ]
[ enableFailFastCheck ="true" | "false" | "1" | "0" ]
[ <baseType> ... </baseType> ]
[ <javadoc> ... </javadoc> ]
</property>
<baseType>
<javaType> ... </javaType>
</baseType>
name defines the customization value propertyName; it must be a legal Java identifier.
collectionType defines the customization value propertyCollectionType, which is the collection type for the property. propertyCollectionType if specified, can be either indexed or any fully-qualified class name that implements java.util.List.
fixedAttributeAsConstantProperty defines the customization value fixedAttributeAsConstantProperty. The value can be either true, false, 1, or 0.
generateIsSetMethod defines the customization value of generateIsSetMethod. The value can be either true, false, 1, or 0.
enableFailFastCheck defines the customization value enableFailFastCheck. The value can be either true, false, 1, or 0. Please note that the JAXB implementation does not support failfast validation.
<javadoc> customizes the Javadoc tool annotations for the property's getter method.
From this link
XSD
<xs:schema targetNamespace="http://thenamespace">
<xs:element name="ViolatingName" type="tns:ViolatingName"/>
<xs:complexType name="ViolatingName">
<xs:all>
<xs:element name="prova" type="xs:string"/>
</xs:all>
</xs:complexType>
<xs:element name="AdditionalInfos" type="AdditionalInfos"/>
<xs:complexType name="AdditionalInfos">
<xs:sequence>
<xs:element minOccurs="1" name="ViolatingName" type="tns:ViolatingName"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Binding
<bindings version="2.0" xmlns="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:annox="http://annox.dev.java.net"
xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix">
<bindings schemaLocation="../path/of/your.xsd">
<bindings node="//xs:complexType[#name='AdditionalInfos']//xs:sequence//xs:element[#name='ViolatingName']">
<property name="aaa" />
</bindings>
</bindings>
</bindings>
Generated Class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "AdditionalInfos", propOrder = {
"aaa",
})
#XmlRootElement
public class AdditionalInfos
implements Serializable
{
private final static long serialVersionUID = 12343L;
#XmlElement(name = "ViolatingName", required = true)
protected ViolatingName aaa;
Related
My wsdl specification contains imported XSD schema.
wsdl file looks like below
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ....>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd2" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svcc?xsd=xsd4" namespace="http://schemas.datacontract.org/2004/07/System.Web.Services.Protocols"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd0" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd1" namespace="http://schemas.datacontract.org/2004/07/ABCUser.Web.Services"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/ABCUser.Web.ServiceModels"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd5" namespace="http://schemas.datacontract.org/2004/07/System"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd6" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd7" namespace="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd8" namespace="http://schemas.datacontract.org/2004/07/ABC.Fs.UIEntities"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd9"/>
</xsd:schema>
</wsdl:types>
.......
</wsdl:definitions>
My jaxb bindings file look like below:
<jaxws:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1"
wsdlLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?wsdl">
<enableWrapperStyle>true</enableWrapperStyle>
<enableAsyncMapping>false</enableAsyncMapping>
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema/xs:complexType[#name='Node']/xs:sequence/xs:element[#name='Type']">
<jaxb:class name="NodeTypeString"/>
</jaxws:bindings>
</jaxws:bindings>
If I don't use bindings.xml, I get following error while generating java classes through wsimport
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 1 of https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd3
[ERROR] (Related to above error) This is the other declaration.
line 1 of https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd3
Schema it is complaining about looks like below
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/ABCUser.Web.ServiceModels" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/ABCUser.Web.ServiceModels">
<xs:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd6" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
.......
<xs:complexType name="Node">
<xs:sequence>
<xs:element minOccurs="0" name="Description" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Type" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Users" nillable="true" type="tns:ArrayOfUser"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Node" nillable="true" type="tns:Node"/>
......
But now when I use bindings.xml, I get the following error
[ERROR] XPath evaluation of "wsdl:definitions/wsdl:types/xs:schema/xs:complexType[#name='Node']/xs:sequence/xs:element[#name='Type']" results in an empty target node
line 8 of file:/E:/projects/codegeneration/bindings.xml
What am I missing? I am using wsimport to generate the classes.
<xsd:import> does not actually change the WSDL file’s XML document tree. You have elements matching wsdl:definitions/wsdl:types/xs:schema/xs:import, not wsdl:definitions/wsdl:types/xs:schema/xs:complexType/xs:sequence/xs:element.
The JAX-WS specification’s “Customizations” chapter says:
Additionally, jaxb:bindings MAY appear inside a JAX-WS external binding file as a child of a jaxws:bindings element whose node attribute points to a xs:schema element inside a WSDL document. When the schema is processed, the outcome MUST be as if the jaxb:bindings element was inlined inside the schema document as an annotation on the schema component.
While processing a JAXB binding declaration (i.e. a jaxb:bindings element) for a schema document embedded inside a WSDL document, all XPath expressions that appear inside it MUST be interpreted as if the containing xs:schema element was the root of a standalone schema document.
So, your inner jaxws:bindings element must contain the XPath of the xs:schema element, not any of its descendants:
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema">
<jaxb:bindings node="xs:complexType[#name='Node']/xs:sequence/xs:element[#name='Type']">
<jaxb:class name="NodeTypeString"/>
</jaxb:bindings>
</jaxws:bindings>
I’m not sure if the above will actually work with a schema that uses <xsd:import>. You may have to refer to the imported schema explicitly:
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema">
<jaxb:bindings schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd2">
<jaxb:bindings node="xs:complexType[#name='Node']/xs:sequence/xs:element[#name='Type']">
<jaxb:class name="NodeTypeString"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxws:bindings>
I got two solutions for this issue I was facing.
I streamlined the wsdl schema by adding imported schema in it and removing import statements.
First build an episode using xjc for imported schema
xjc -episode myschema.episode myschema.xsd
And then use that episode as a binding in java classes generation through wsimport
wsimport mywsdl.wsdl -b myschema.episode
More about 2nd solution here
I am using JAXB 2.0. I have various elements and types defined in an XSD file. Here's an example:
<xs:element name="Person" type="Person" />
<xs:complexType name="Person">
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:element name="Musician" type="Musician"/>
<xs:complexType name="Musician">
<xs:complexContent>
<xs:extension base="Person">
<xs:attribute name="instrument" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="People" type="People"/>
<xs:complexType name="People">
<xs:sequence>
<xs:element name="person" type="Person" minOccurs="0" maxOccurs="Unbounded/>
</xs:sequence>
</xs:complexType>
So as you can see from the above schema example, we have a Person, who has a name, and a Musician, who is also a Person (though this may be subject to some debate, but that's for another forum). There is also a People element, which is essentially a collection of Person types.
I have the following in a bindings file:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0"
xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc">
<jaxb:globalBindings optionalProperty="wrapper">
<xjc:simple/>
</jaxb:globalBindings>
My intended use of these objects is:
A Person may appear as a solitary Marshalled element, or may be a part of a People object
If a Person is part of a People object, then the xsi:type should indicate whether it's just a normal Person or a Musician.
So I need the generated Java classes to contain both an #XmlRootElement annotation as well as an #XmlType annotation. The xjc:simple binding creates both annotations for a Musician, but only creates the #XmlType for Person. So when I Marshall a Person object, all I get is:
<?xml version="1.0" encoding="UTF-8"?>
Whereas what I would like to see is:
<?xml version="1.0" encoding="UTF-8"?>
<Person name="John Doe"/>
For a People object, I want to see:
<?xml version="1.0" encoding="UTF-8"?>
<People>
<person name="John Doe" xsi:type="Person"/>
<person name="Keith Richards" xsi:type="Musician"/>
</People>
I have read about the simple binding with xjc, and it works with all the lowest levels in an inheritance hierarchy. However, the base classes end up without an #XmlRootElement annotation. For the use case I'm working on, it's imperative that base classes can be Marshalled as both a top-level element and as a member of other elements. Any suggestions would be welcome.
https://github.com/highsource/jaxb2-annotate-plugin could be used
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:annox="http://annox.dev.java.net"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.1"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc annox">
<jaxb:bindings node="//xs:complexType[#name='Person']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="person"/>
</annox:annotate>
</jaxb:bindings>
</jaxb:bindings>
When I run xjc to generate a Java type representing this XSD snippet:
<xs:complexType name="fileUploadRequest">
<xs:choice>
<xs:element name="path" type="xs:string"/>
<xs:element name="file" type="xs:base64Binary"/>
</xs:choice>
</xs:complexType>
I get a class that's indistinguishable from what it would have been if I'd specified a sequence with optional elements instead.
I want a type with a little bit of intelligence, that'll let me have at most 1 element of my choice at a time. If I invoke the generated setFile method for example, it should make the path null. Is there some plugin I can use for what seems like an obvious requirement of a code generator?
binding.xml
You can use the following external binding file to generate the type of property you are looking for:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<globalBindings choiceContentProperty="true"/>
</bindings>
XJC Call
The binding file is referenced using the -b flag.
xjc -b binding.xml schema.xsd
Generated Property
Now the following property will be generated:
#XmlElements({
#XmlElement(name = "path", type = String.class),
#XmlElement(name = "file", type = byte[].class)
})
protected Object pathOrFile;
For More Information
http://blog.bdoughan.com/2011/04/xml-schema-to-java-xsd-choice.html
Running the following xjc command raises an error :
$ xjc "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd"
parsing a schema...
compiling a schema...
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 340 of ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd
[ERROR] (Related to above error) This is the other declaration.
line 475 of ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd
Although I understand the JAXB bindings and what are is conflict in XJC, I don't understand where is the conflict in the current schema.
how should I fix this ?
Thanks,
Pierre
update: here is the context of the errors:
$ curl -s "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd" | sed 's/^[ \t]*//' | cat -n | egrep -w -A 10 -B 10 '(340|475)'
330 <xs:element maxOccurs="1" name="Description"
331 type="xs:string" minOccurs="0">
332 <xs:annotation>
333 <xs:documentation>
334 Optionally provide description especially when "eOther" is selected
335 </xs:documentation>
336 </xs:annotation>
337 </xs:element>
338 <xs:element name="BioSampleSet" minOccurs="0" maxOccurs="1"><xs:annotation><xs:documentation>Identifier of the BioSample when known</xs:documentation>
339 </xs:annotation>
340 <xs:complexType><xs:sequence><xs:element name="ID" maxOccurs="unbounded" type="xs:token"></xs:element>
341 </xs:sequence>
342 </xs:complexType>
343 </xs:element>
344 </xs:sequence>
345 <xs:attribute name="sample_scope" use="required">
346 <xs:annotation>
347 <xs:documentation>
348 The scope and purity of the biological sample used for the study
349 </xs:documentation>
350 </xs:annotation>
--
465 <xs:documentation>Please, fill Description element when choose "eOther"</xs:documentation>
466 </xs:annotation>
467 </xs:enumeration>
468 </xs:restriction>
469 </xs:simpleType>
470 </xs:attribute>
471 </xs:complexType>
472 </xs:element>
473 <xs:element name="TargetBioSampleSet">
474 <xs:annotation><xs:documentation>Set of Targets references to BioSamples</xs:documentation></xs:annotation>
475 <xs:complexType>
476 <xs:sequence>
477 <xs:element name="ID" type="xs:token" minOccurs="1" maxOccurs="unbounded"></xs:element>
478 </xs:sequence>
479 </xs:complexType>
480 </xs:element>
481 </xs:choice>
482 <xs:element name="Method" minOccurs="1">
483 <xs:annotation>
484 <xs:documentation>
485 The core experimental approach used to obtain the data that is submitted to archival databases
I'll quote from the most official unofficial guide on JAXB on the net.
When schemas contain similar looking element/type names, they can
result in "Two declarations cause a collision in the ObjectFactory
class" errors. To be more precise, for each of all types and many
elements (exactly what elements get a factory and what doesn't is bit
tricky to explain), XJC produces one method on the ObjectFactory class
in the same package. The ObjectFactory class is created for each
package that XJC generates some files into. The name of the method is
derived from XML element/type names, and the error is reported if two
elements/types try to generate the same method name.
That said, you have two options.
The first is to define an external binding XML like this
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<jaxb:bindings schemaLocation="Core.xsd">
<jaxb:bindings node="//xs:element[#name='BioSampleSet']/xs:complexType">
<jaxb:factoryMethod name="TypeBioSampleSet"/>
</jaxb:bindings>
<jaxb:bindings node="//xs:element[#name='TargetBioSampleSet']/xs:complexType">
<jaxb:factoryMethod name="TypeTargetBioSampleSet"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
In the generated ObjectFactory class this will create two methods called createTypeBioSampleSet and createTypeTargetBioSampleSet (JAXB will append the name you specify to the word create) that can be used to produce BioSampleSet and TargetBioSampleSet objects.
(It's not necessary to define a binding for both types.)
I'm not exactly sure why JAXB refuses to generate classes from the given schema, but when I specified only one binding (for BioSampleSet for example) then the other type's factory method was named like createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse so I think JAXB choked on this long method identifier, because it somehow managed to create the same one for both types. I think this is some implementation detail in JAXB.
The other solution is to create a base type for a BioSampleSet and use that at both locations like this
<xs:element name="ProjectTypeSubmission">
...
<xs:element name="Target">
...
<xs:element name="BioSampleSet" type="typeBioSampleSet" minOccurs="0" maxOccurs="1"/>
...
</xs:element>
...
<xs:element name="TargetBioSampleSet" type="typeBioSampleSet"/>
...
<xs:element/>
...
<xs:complexType name="typeBioSampleSet">
<xs:sequence>
<xs:element name="ID" maxOccurs="unbounded" type="xs:token"></xs:element>
</xs:sequence>
</xs:complexType>
The best solution would be to drop every anonymous type declarations from your schema. If you can do that, do it, because this schema looks like a mess (to me at least).
remove -p package in the command
xjc -d src -XautoNameResolution TFMData_Service.xsd
I had the same problem, collision of object factory, and my solution was to use the following binding:
<jaxb:bindings version="1.0"
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"
jaxb:extensionBindingPrefixes="xjc">
<jaxb:bindings
schemaLocation="../pfel_xsd/pfel-mng-managedocument-v4-vs_data.xsd"
node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="document.client.pfelservice"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings
schemaLocation="../pfel_xsd/pfel-mng-managedocument-v4-vs_data-types.xsd"
node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="document.client.pfel"/>
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
Here's the solution: https://www.javaer101.com/en/article/1278220.html
The solution that worked for me when using the below maven plugin is adding -XautoNameResolution
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
Sample code:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<xjbSources>
<xjbSource>src/main/resources/global.xjb</xjbSource>
</xjbSources>
<sources>
<source>src/main/xsd/</source>
</sources>
<arguments>
<argument>-XautoNameResolution</argument>
</arguments>
<packageName>com.xxx.yyy.zzz.policy.xml</packageName>
</configuration>
</plugin>
I faced a similar issue with name collisions in the ObjectFactory class.
One of the problems was that in default settings XJC generates a more verbose Java model with intermediate types. This causes collisions among the required model objects and the intermediate model objects.
The solution was to use the XLC simple binding mode. This eliminates the intermediate model objects, which in turn solves the collision problem.
To enable this, add this binding file:
<jxb:bindings version="1.0"
xmlns:jxb="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">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
</jxb:bindings>
An example of how the ObjectFactory looks much simplified for the same XSD before and after the simple binding setting. (Note the Citation and CitationX elements which were colliding earlier and I had fiddled with renaming one of them to CitationX.)
For more information on Simple bindings, refer:
https://stackoverflow.com/a/5155704/1364747
https://stackoverflow.com/a/13359717/1364747
In my case, the cause was that I had specified a target package when running wsimport which meant that all the generated classes were in the same package. The default behaviour of wsimport is to generate code in packages based on the namespace specified in schema tags, which is what you generally want.
Use case:
Wanna insert custom annotation to fields in java class generated by JAXB
Problem:
Using Annotate plugin + JAXB [1], am able to successfully insert custom annotations but they are getting inserted at getter method rather than field. Morphia (mongo DB) annotations (that i actually want to insert) however can annotate only java fields [2].
My test xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1"
xmlns:annox="http://annox.dev.java.net" jaxb:extensionBindingPrefixes="annox">
<xsd:element name="hoo" type="External" />
<xsd:complexType name="External">
<xsd:sequence>
<xsd:element name="bar" type="xsd:string" />
<xsd:element name="hoobar" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
My test binding xjb:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings
version="2.1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:annox="http://annox.dev.java.net" jaxb:extensionBindingPrefixes="annox">
<jaxb:bindings schemaLocation="external.xsd" node="/xs:schema">
<jaxb:bindings node="xs:complexType[#name='External']/xs:sequence/xs:element[#name='bar']">
<annox:annotate>
<annox:annotate
annox:class="java.lang.SuppressWarnings"
impl="com.acme.foo.MyFieldBridge">
</annox:annotate>
</annox:annotate>
</jaxb:bindings>
My generated java snippet:
#XmlElement(required = true)
protected String bar;
#XmlElement(required = true)
protected String hoobar;
/**
* Gets the value of the bar property.
*
* #return
* possible object is
* {#link String }
*
*/
#SuppressWarnings({
})
public String getBar() {
return bar;
}
As you can see, i want to annotate "bar" field. Please advise. Ask for more if needed.
[1] Generate #Indexed annotation using Jaxb or HyperJaxb
[2] For sample see #Id annotation of Morphia
Ok, you figured it out yourself. Use <annox:annotate target="field"> to annotate a field. Other options are:
setter
setter-parameter
getter
field
class
See the documentation.
Just one more thing: you need to put the field attribute to the outer <annox:annotate> tag:
<annox:annotate target="field">
<annox:annotate annox:class="java.lang.SuppressWarnings"/>
</annox:annotate>
Putting it to the same tag as the annox:class attribute resides might not work. That happend to me.