10

I'm running a wsimport task with the following bindings file:

<jaxb:bindings version="2.1"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <jaxb:bindings>
        <jaxb:globalBindings generateElementProperty="false" typesafeEnumMaxMembers="2000" />
    </jaxb:bindings>
</jaxb:bindings>

However, this is resulting in classes with JAXBElement<String> instead of String as shown in the getUserSummaryOrTypeOrLogLevel() below

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ConfigSLMAction", propOrder = {
    "userSummaryOrTypeOrLogLevel"
})
public class ConfigSLMAction
    extends ConfigConfigBase
{

    @XmlElementRefs({
        @XmlElementRef(name = "UserSummary", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "LogLevel", type = JAXBElement.class, required = false),
        @XmlElementRef(name = "Type", type = JAXBElement.class, required = false)
    })
    protected List<JAXBElement<String>> userSummaryOrTypeOrLogLevel;
    @XmlAttribute(name = "name")
    protected String name;
    @XmlAttribute(name = "local")
    protected Boolean local;
    @XmlAttribute(name = "intrinsic")
    protected Boolean intrinsic;
    @XmlAttribute(name = "read-only")
    protected Boolean readOnly;
    @XmlAttribute(name = "external")
    protected Boolean external;

    /**
     * Gets the value of the userSummaryOrTypeOrLogLevel property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the userSummaryOrTypeOrLogLevel property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getUserSummaryOrTypeOrLogLevel().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * 
     * 
     */
    public List<JAXBElement<String>> getUserSummaryOrTypeOrLogLevel() {
        if (userSummaryOrTypeOrLogLevel == null) {
            userSummaryOrTypeOrLogLevel = new ArrayList<JAXBElement<String>>();
        }
        return this.userSummaryOrTypeOrLogLevel;
    }
    ...
    ...
    ...
}

The entry in the xsd file that this class is being generated from is below:

<xsd:complexType name="ConfigSLMAction">
    <xsd:complexContent>
        <xsd:extension base="tns:ConfigConfigBase">
            <xsd:choice maxOccurs="unbounded">
                <xsd:element name="UserSummary" minOccurs="0" maxOccurs="1">
                    <xsd:simpleType>
                        <xsd:union memberTypes="tns:dmString tns:dmEmptyElement" />
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="Type" minOccurs="1" maxOccurs="1">
                    <xsd:simpleType>
                        <xsd:union memberTypes="tns:dmSLMActionType tns:dmEmptyElement" />
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="LogLevel" minOccurs="0" maxOccurs="1">
                    <xsd:simpleType>
                        <xsd:union memberTypes="tns:dmLogLevel tns:dmEmptyElement" />
                    </xsd:simpleType>
                </xsd:element>
            </xsd:choice>
            <xsd:attributeGroup ref="tns:ConfigAttributes" />
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

Here's the Maven plugin from my pom file

<plugin>
    <groupId>org.jvnet.jax-ws-commons</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.3</version>
    <executions>
        <execution>
            <id>wsimport-from-jdk</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>wsimport</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <wsdlFiles>
            <wsdlFile>${basedir}/src/main/resources/wsdl/xml-mgmt.wsdl</wsdlFile>
        </wsdlFiles>
        <bindingFiles>
            <bindingFile>${basedir}/src/main/resources/wsdl/bindings.xml</bindingFile>
        </bindingFiles>
        <keep>true</keep>
        <verbose>true</verbose>
        <extension>true</extension>
        <vmArgs>
            <vmArg>-Djavax.xml.accessExternalDTD=all</vmArg>
            <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
        </vmArgs>
    </configuration>
</plugin>

Can anyone shed some light on why this is happening? I want String to be used instead of JAXBElement<String> and anything I've found on SO and elsewhere suggests that generateElementProperty=false work but it isn't.

conorgriffin
  • 4,282
  • 7
  • 51
  • 88
  • ok I found similar question: http://stackoverflow.com/questions/22513736/jaxb-avoid-jaxbelement and problem is with choice element. – hudi Jul 13 '15 at 11:59

2 Answers2

14

The JAXBElement is mandatory if there is a xsd:choice where either foo or bar elements can occur and they are the same type. A simple String isn't enough to mark which element should be marshalled.

JAXBElement is required also if there are element nillable="true" and minOccurs="0" or if there are two global elements with the same named xsd:complexType.

Xstian
  • 8,184
  • 10
  • 42
  • 72
1

can you try another plugin to make sure error is in JAXB ? In our project we are using:

        <plugin>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-codegen-plugin</artifactId>
            <executions>
                <execution>
                    <id>generate-sources-ais</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <defaultOptions>
                            <bindingFiles>
                                <bindingFile>${basedir}/src/main/resources/wsdl/binding/bindings.xml</bindingFile>
                            </bindingFiles>
                        </defaultOptions>
                        <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                        <wsdlRoot>${basedir}/src/main/resources/wsdl</wsdlRoot>
                        <includes>
                            <include>**/*.wsdl</include>
                        </includes>
                    </configuration>
                    <goals>
                        <goal>wsdl2java</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

and it works as you expecting

UPDATE:

you are right plugin is ok. It is because choice element. Probably duplicated with this

Community
  • 1
  • 1
hudi
  • 15,555
  • 47
  • 142
  • 246
  • Got the same output with `JAXBElement` but I couldn't use the `-xjc-Xinheritance` as the plugin threw an error – conorgriffin Jul 13 '15 at 10:08
  • ah sorry you can miss this arg. You need it just when you use inheritence in binding.xml and then you need another dependency. I will update xml – hudi Jul 13 '15 at 10:12
  • I left the arg out anyway, still got the same output classes as when I used the `jaxws-maven-plugin` – conorgriffin Jul 13 '15 at 10:13
  • hm can you provide whole xml-mgmt.wsdl and xsd so can try it ? Or at least whole xsd element ConfigSLMAction – hudi Jul 13 '15 at 10:17
  • The whole XSD element is included in the question. I can't provide the WSDL I'm afraid as it's protected by copyright – conorgriffin Jul 13 '15 at 10:37