You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Edward Wertz <ed...@mindreef.com> on 2003/04/18 22:08:48 UTC

Quirks/Bugs using WSDL2Java

I have run across a few quirks using WSDL2Java on a hand-rolled WSDL.  The first quirk deals with void operations which need no arguments. The second quirk deals with operations which return the same message type as they receive.  The WSDL I'm referring to follows at the end of the mail. 

Quirk 1) boolean getDebugState()

The signature of getDebugState is ()->boolean.  But the stub code generated actually creates a class _GetDebugState to reflect the name of the input message's element.  The java code I have to use looks like:

 boolean foo = stub.getDebugState(new _GetDebugState());

If I change the name of the operation from "getDebugState" to "GetDebugState" the proper stub code is generated and allowing me to make the call with the following function call:

 boolean foo = stub.GetDebugState();

For some reason if the names are exactly the same, the stub code looks right.  If the names are different the stub code requires me to create a _GetDebugState object which has the basic stub code functionality for an object but no other meaningful fields or operations.  The call works fine, given one of these "void objects" but I don't see any reason for it to be made. 


Quirk 2) boolean setDebugState(boolean state)

The signature of setDebugState is boolean->boolean.  And the message signature looks like DebugState->DebugState.  The operation takes the same message as it returns.  AFAIK this isn't wrong, but the stub code signature looks like boolean->().  WSDL2Java didn't like the fact that the message going in and the message coming out were the same.  Copying the message declaration and changing its name from "DebugState" to "DebugState2" wasn't enough.  I had to change the wsdl:part name within the message from "debugState" to "debugState2" before the signature was right. 

There was also a bug in the service I was using.  The wsdl said setDebugState was boolean->boolean, but the request-response pattern was actually boolean->(), the response soap:body had no content.  I thought that was ironic (note previous paragraph) until I got a null pointer exception when the stub code made by WSDL2Java tried to retrieve a boolean from the message.  The signature of the stub code operation says the return value is void, but the operation itself tries to set the return value of the operation to boolean.  Because the value wasn't in the message it created a null pointer exception.  There must be a split personality in WSDL2Java somewhere, the code generated isn't consistent with the interface returned.  The generated code knew the wsdl said the function was boolean->boolean but the interface generator thought it was boolean->() because the part names were the same. 

by the by,  shouldn't there be a better exception produced when a SOAP message doesn't contain the data that you expect?  A null pointer exception is a little uncouth.  

I looked at bugzilla and didn't see anything that resembled this.  Should I go ahead and add it? 

Thanks, 

Edward


WSDL)


<definitions targetNamespace="http://www.mindreef.com/soapscope/2.0/api"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ss="http://www.mindreef.com/soapscope/2.0/api">
   <types>
      <xs:schema targetNamespace="http://www.mindreef.com/soapscope/2.0/api" elementFormDefault="qualified" attributeFormDefault="unqualified">
         <xs:element name="SessionId" type="xs:long" />
         <xs:element name="NewSession">
            <xs:complexType />
         </xs:element>
         <xs:element name="GetDebugState">
            <xs:complexType />
         </xs:element>
         <xs:element name="GetSession">
            <xs:complexType />
         </xs:element>
         <xs:element name="DebugState" type="xs:boolean" />
      </xs:schema>
   </types>
   <message name="NewSession">
      <part name="parameters" element="ss:NewSession" />
   </message>
   <message name="SessionId">
      <part name="sessionId" element="ss:SessionId" />
   </message>
   <message name="GetDebugState">
      <part name="void" element="ss:GetDebugState" />
   </message>
   <message name="GetSession">
      <part name="void" element="ss:GetSession" />
   </message>
   <message name="DebugState">
      <part name="debugState" element="ss:DebugState" />
   </message>
   <portType name="SOAPscopeEngine">
      <operation name="newSession">
         <input message="ss:NewSession" />
         <output message="ss:SessionId" />
      </operation>
      <operation name="getSession">
         <input message="ss:GetSession" />
         <output message="ss:SessionId" />
      </operation>
      <operation name="getDebugState">
         <input message="ss:GetDebugState" />
         <output message="ss:DebugState" />
      </operation>
      <operation name="setDebugState">
         <input message="ss:DebugState" />
         <output message="ss:DebugState" />
      </operation>
   </portType>
   <binding name="SOAPscopeEngine" type="ss:SOAPscopeEngine">
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
      <operation name="newSession">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
      <operation name="getSession">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
      <operation name="getDebugState">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
      <operation name="setDebugState">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
   </binding>
   <service name="SOAPscopeEngine">
      <port name="SOAPscopeEngine" binding="ss:SOAPscopeEngine">
         <soap:address location="http://localhost:7103/api/engine" />
      </port>
   </service>
</definitions>