Uploaded image for project: 'Axis2'
  1. Axis2
  2. AXIS2-928

Not all added header elements are included in outgoing SOAP header unless run under debugger - bug in OMElement caching?

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.0
    • Fix Version/s: None
    • Component/s: client-api
    • Labels:
      None

      Description

      Hi, folks.

      I have two custom headers, CARSLogin and CARSPassword, that are declared and used in my WSDL like so:

      <types>
      <xs:schema targetNamespace="http://www.c-corp.com/wsdl/2004-10-01/f">
      <xs:import namespace="http://www.dummy-temp-address" schemaLocation="F.xsd"/>
      <xs:element name="return" type="xs:string"/>
      <xs:element name="failure" type="xs:string"/>
      </xs:schema>
      <xs:schema targetNamespace="http://www.c-corp.com/wsdl/2004-10-01/C">
      <xs:element name="CPassword" type="xs:string"/>
      <xs:element name="CLogin" type="xs:string"/>
      </xs:schema>
      </types>

      <message name="FEvent">
      <part name="contents" element="f:full-event-update"/>
      </message>

      <message name="FResponse">
      <part name="return" element="tns:return"/>
      </message>

      <message name="CPassword">
      <part name="CPassword" element="C:CPassword"/>
      </message>

      <message name="CLogin">
      <part name="CLogin" element="C:CLogin"/>
      </message>

      <message name="Failure">
      <part name="faultDetail" element="tns:failure"/>
      </message>

      <portType name="FPortType">
      <documentation>F Port Type</documentation>

      <operation name="acceptFEvent" parameterOrder="contents">
      <input name="acceptFEventRequest" message="tns:FEvent"/>
      <output name="acceptFEventResponse" message="tns:FResponse"/>
      <fault name="Failure" message="tns:Failure"/>
      </operation>

      </portType>

      <binding name="FSoapBinding" type="tns:FPortType">
      <documentation>F Soap Binding</documentation>
      <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

      <operation name="acceptFEvent">
      <soap:operation soapAction="acceptFEventAction"/>
      <input>
      <soap:header message="tns:CLogin" part="CLogin" use="literal"/>
      <soap:header message="tns:CPassword" part="CPassword" use="literal"/>
      <soap:body use="literal"/>
      </input>
      <output>
      <soap:body use="literal"/>
      </output>
      <fault name="Failure">
      <soap:fault name="Failure" use="literal"/>
      </fault>
      </operation>
      </binding>

      Now, when I use WSDL2Java to generate XMLBeans Java code for these, and try to write a client that will send a message in this format, I write something like this:

      final CLoginDocument login = CLoginDocument.Factory.newInstance();
      login.setCLogin( "testlogin" );
      final CPasswordDocument password = CPasswordDocument.Factory.newInstance();
      password.setCPassword( "testpassword" );
      final FServiceStub service = new FServiceStub( null, targetEndpoint );
      final FullEventUpdateDocument fullEventUpdate = FullEventUpdateDocument.Factory.newInstance();
      fullEventUpdate.setFullEventUpdate( getSituation() );
      return service.acceptFEvent( fullEventUpdate, login, password );

      This seems reasonable, and mostly works. Except that when I look at the SOAP output using TCPMon, the SOAP header that is included in the outgoing SOAP message contains the CLogin element as expected, but totally omits the CPassword element . I can find no reason for this. Both were passed to the stub, and both are non-null, so both should be included in the output.

      When I step through the code in the stub using a debugger, however, then the code seems to correctly generate the header including both the login and password, as I would expect. So this is a stereotypical "heisenbug" as per the Jargon File: everything works fine when I run it under the debugger and watch what is happening, but it fails when run normally.

      My theory is that the debugger is calling toString() on various items such as the SOAP envelope which is constructed to contain both the CLogin and CHeader elements. I suspect that calling toString() in this fashion forces the underlying OMElements to cache the results of parsing the XML, and that when it comes time to generate the SOAP message for output, reading from this cache works differently from parsing the header elements directly somehow.

      Regardless, this seems like a pretty serious bug in Axis2: If I add multiple header elements to a message, I expect that they all should be included in the outgoing SOAP message, but that is not happening unless I run the program under a debugger. The fact that this is nondeterministic hints at a caching or multithreading bug at some level within the Axis architecture, which is quite worrisome, since the process of formatting and sending a SOAP message should be completely deterministic and repeatable.

      Derek

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                eran chinthaka Eran Chinthaka
                Reporter:
                derekfoster Derek Foster
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: