Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve collision in the ObjectFactory on wsdl2java?

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.

like image 477
membersound Avatar asked Sep 22 '14 14:09

membersound


3 Answers

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>
like image 64
membersound Avatar answered Nov 09 '22 23:11

membersound


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.

like image 25
lexicore Avatar answered Nov 10 '22 01:11

lexicore


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;
like image 1
Xstian Avatar answered Nov 10 '22 01:11

Xstian