0

I use Apache Camel + JAXB for Soap processing. The java glasses are generated by a maven plugin called cxf-codegen-plugin.

The Problem I am facing is that when I want to use a property which is a list. In that case I will always get a list of JAXBElement instead of objects of the correct class.

Assume this given xml snipped:

<domainObjects avqxsi:type="avqsq:AssetAllocation" id="100" name="Some Name">
    <nodes>101</nodes>
    <nodes>102</nodes>
  </domainObjects>

Now all the "nodes" are ids of different domain objects of type AANode. So in the xsd it is defined like so:

<xsd:complexType name="AssetAllocation">
    <xsd:complexContent>
      <xsd:extension base="avqsq:DomainObject">
        <xsd:sequence>
          <xsd:element ecore:reference="avqsq:AANode" maxOccurs="unbounded" name="nodes" type="xsd:IDREF"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

And I have defined some bindings.xml:

<jaxb:bindings node="xsd:complexType[@name='AssetAllocation']//xsd:element[@name='nodes']">
            <jaxb:property>
                <jaxb:baseType name="my.api.xsd.AANode"/>
            </jaxb:property>
        </jaxb:bindings>

What I want is a POJO property like this:

@XmlElementRef(name = "nodes")
protected List<AANode> nodes;

But what I actually get at runtime is a List<JAXBElement<AANode>> which leads into a ClassCastException.

EDIT 1: I have missed the fact that the cxf-codegen framework is generating a class where you clearly can see that the property is annotated with JAXBElement.class which i think is wrong. Interestingly changing the annotation by hand to AANode.class will fail with an IllegalAnnotationException: AANode" or any of its subclasses are not known to this context.

public class AssetAllocation
    extends DomainObject
    implements Serializable, Equals, HashCode, ToString
{

    @XmlElementRef(name = "nodes", type = JAXBElement.class)
    protected List<AANode> nodes;
KIC
  • 5,887
  • 7
  • 58
  • 98

2 Answers2

1

apache CXF code gen plugin will always generate codes with JAXBElement until you set the generate element property flag.

Please create Jaxb binding.xml and refer that binding xml in your code gen plugin section from pom file as below

binding.xml

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.0"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
    <jaxb:bindings>
        <jaxb:globalBindings generateElementProperty="false"/>
    </jaxb:bindings>
</jaxb:bindings>

code gen plugin

<plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                        <configuration>
                            <wsdlOptions>
                                <wsdlOption>
                                    <wsdl>${basedir}/src/main/resources/META-INF/wsdl/CxfExampleService.wsdl</wsdl>
                                    <bindingFiles>
                                        <bindingFile>${basedir}/src/main/resources/META-INF/wsdl/binding/bindings.xml</bindingFile>
                                    </bindingFiles>                                 
                                </wsdlOption>
                            </wsdlOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

This will resolve the issue

Gnana Guru
  • 715
  • 5
  • 11
  • Hmm I have tried this and it is also documented this way but I am not able to get the expected behavior. – KIC Aug 27 '15 at 14:53
0

In fact the wsdl2java generates classes with wrong annotations. Instead of

@XmlElementRef(name = "nodes", type = JAXBElement.class)
protected List<AANode> nodes;

One would expect to have:

@XmlIDREF
protected List<AANode> nodes;

I was not able to manage this by bindings.xml. So my final solution is that I use a Byte-Code manipulation to fix the annotations. That way I do not have to mess around with the generated classes or with the generator itself.

KIC
  • 5,887
  • 7
  • 58
  • 98