1

I have created java based web service and noticed an interesting way wsimport treats jaxb parameters/return objects. When a web method returns a jaxb object wsimport creates it as a sub-object (Nested) of that method.

An example... let us say I have a method called GetRoles() that returned a jaxb generated object called RoleAdministration. Wsimport generates the following nested object: GetRoles.RoleAdministration.

However if the same method returned a plain old serialized java object it gets returned by wsimport as RoleAdministration. This seems to be better to me since I can use this for other web methods that happen to use it as a parameter or a return type.

A) Why does the object being jaxb generated change the way wsimport generates it? B) Is there anything special to force wsimport to 'flatten' parameter and return objects?

As requested:

<?xml version="1.0"?>
<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/maven-v4_0_0.xsd">


<groupId>com.server</groupId>

<artifactId>Server-WEB</artifactId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>

<name>Server-WEB</name>

<properties>
</properties>
   <build>
      <plugins>
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>2.5.1</version>
       <configuration>
           <source>1.8</source>
           <target>1.8</target>
       </configuration>
   </plugin>
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-war-plugin</artifactId>
       <configuration>
           <failOnMissingWebXml>false</failOnMissingWebXml>
           <webResources>
               <resource>
                   <directory>src</directory>
                   <targetPath>WEB-INF</targetPath>
                   <includes>
                       <include>jax-ws-catalog.xml</include>
                       <include>wsdl/**</include>
                   </includes>
               </resource>
           </webResources>
       </configuration>
   </plugin>
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-dependency-plugin</artifactId>
       <version>2.1</version>
       <executions>
           <execution>
               <phase>validate</phase>
               <goals>
                   <goal>copy</goal>
               </goals>
               <configuration>
                   <outputDirectory>${endorsed.dir}</outputDirectory>
                   <silent>true</silent>
                   <artifactItems>
                       <artifactItem>
                           <groupId>javax</groupId>
                           <artifactId>javaee-endorsed-api</artifactId>
                           <version>6.0</version>
                           <type>jar</type>
                       </artifactItem>
                   </artifactItems>
               </configuration>
           </execution>
       </executions>
   </plugin>
   <plugin>
       <groupId>org.jvnet.jax-ws-commons</groupId>
       <artifactId>jaxws-maven-plugin</artifactId>
       <version>2.2</version>
       <executions></executions>
       <dependencies>
           <dependency>
               <groupId>javax.xml</groupId>
               <artifactId>webservices-api</artifactId>
               <version>1.4</version>
           </dependency>
       </dependencies>
       <configuration>
           <sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir>
           <xnocompile>true</xnocompile>
           <verbose>true</verbose>
           <extension>true</extension>
           <catalog>${basedir}/src/jax-ws-catalog.xml</catalog>
       </configuration>
   </plugin>
     </plugins>
  </build>
  <dependencies>
     <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-core</artifactId>
        <version>1.8</version>
        <type>jar</type>
     </dependency>
     <dependency>
     <groupId>javax</groupId>
     <artifactId>javaee-api</artifactId>
     <version>7.0</version>
     <scope>provided</scope>
 </dependency>
 <dependency>
     <groupId>org.glassfish.metro</groupId>
     <artifactId>webservices-rt</artifactId>
     <version>2.3</version>
     <scope>provided</scope>
 </dependency>
  </dependencies>

EDIT: First block is how the same object looks without jaxb annotations and the second block is how it looks with the jaxb annotations.

<xs:complexType name="RoleResponse">
<xs:sequence>
<xs:element name="code" type="xs:int"/>
<xs:element name="message" type="xs:string" minOccurs="0"/>
<xs:element name="roleAdministration" type="tns:RoleAdministrationDSO"   minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RoleAdministrationDSO">
<xs:sequence>
<xs:element name="dusfe" type="xs:string" minOccurs="0"/>
<xs:element name="roles" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Role" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="FunctionalArea" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>

And here is the jaxb version:

        <xs:complexType name="RoleResponse">
    <xs:sequence>
    <xs:element name="code" type="xs:int"/>
    <xs:element name="message" type="xs:string" minOccurs="0"/>
    <xs:element name="roleAdministration" minOccurs="0">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Roles">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Role" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="FunctionalArea" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Privledge" maxOccurs="unbounded">
    <xs:complexType>
    <xs:sequence/>
    <xs:attribute name="Name" type="xs:string"/>
    <xs:attribute name="Active" type="xs:boolean"/>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    <xs:attribute name="Name" type="xs:string"/>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    <xs:attribute name="Name" type="xs:string" use="required"/>
    <xs:attribute name="RoleID" type="xs:string"/>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    <xs:attribute name="dusfe" type="xs:string" use="required"/>
    <xs:attribute name="Version" type="xs:string" use="required"/>
    <xs:attribute name="Validation" type="xs:string" use="required"/>
    <xs:attribute name="ServerType" type="xs:int"/>
    <xs:attribute name="Message" type="xs:string"/>
    <xs:attribute name="Code" type="xs:int"/>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
JMag
  • 31
  • 6
  • It would be useful if you posted the WSDL because likely this is not a problem that can be fixed with wsimport, but rather something that needs to be changed in how your WSDL is being generated. A [simplified] example of your web service would be helpful as well. – Jason Wheeler Aug 11 '15 at 20:24
  • If what you are saying is true then why are the generated results inconsistent with wsimport? The only factor that changes is whether or not a jaxb object is used. At this time I can not post the wsdl. I can tell you that it is in a maven project and uses metro 2.3. I can post my pom: – JMag Aug 11 '15 at 20:34
  • Like I said, I don't think the problem is with wsimport. You should inspect the WSDL to see how the JAXB objects are represented compared to the other objects and then go from there. – Jason Wheeler Aug 11 '15 at 20:48
  • Thank you. I will take a look and see how the wsdl objects differ. I expect you are correct. How is it a jaxb annotated object that is identical to another object (minus the annotations) would cause a different behavior? I'm using WebService, WebMethod and WebParam annotations from the javax.jws package. – JMag Aug 12 '15 at 13:32
  • JAX-WS, which is the Java standard for SOAP, uses JAXB for the XML pieces. So it would make sense that an object with JAXB annotations could be presented differently. In fact, typically you use JAXB annotations to control how objects are represented in the WSDL. For instance, to prevent a field from being displayed, you annotate the field with @javax.xml.bind.annotation.XMLTransient, which is a JAXB annotation. – Jason Wheeler Aug 12 '15 at 23:18
  • Took a look at annotations and didn't see any that will solve this. I am updating my question above with the wsdl version of the jaxb and non-jaxb object. But it is no surprise the jaxb annotated version is exploded into that response while the other one simply references an object (and works much better). – JMag Aug 13 '15 at 13:35

1 Answers1

1

Finally found someone who had the ability to solve this. The two important parts are setting a name space in the xsd response/parameter objects and using the WebResult and Namespace annotations directly on the methods them self. The strange behavior I was experiencing comes directly from issues wsimport has with XmlRootElement.

reference Why does wsimport have trouble with server object having @XmlRootElement annotation?

Community
  • 1
  • 1
JMag
  • 31
  • 6