Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.5.2
    • Fix Version/s: 1.5.3
    • Component/s: Core
    • Labels:
      None
    • Environment:
      WinXP, Java 1.5, Axiom 1.2.7, HttpClient 3.1

      Description

      Incoming SOAP messages with attachments are parsed correctly, but outgoing messages with attachments are missing attachment parts and all part boundaries, even though the overall HTTP content-type is "multipart/related" with a boundary value specified.

      Given this message sending scenario:

      WebServiceMessageCallback requestCallback = new WebServiceMessageCallback() {
        public void doWithMessage(WebServiceMessage message)
            throws IOException, TransformerException {
          
          SoapMessage soapMessage = (SoapMessage) message;
            
          soapMessage.addAttachment(
              generateContentId(), // generates a unique Content-ID String
              new ByteArrayResource(attachmentData),   // Data
              "application/octet-stream");        // Content-Type
        }
      }; 
       
      // ...create response extractor ....
       
      serviceTemplate.sendAndReceive(
        "https://foo.bar.com/SendSubmissionReceipts", 
        requestCallback, responseExtractor);

      I get an HTTP message like this:

      Accept-Encoding: gzip
      Content-Type: multipart/related; boundary=MIMEBoundaryurn_uuid_3D927F4433B32F68641210953465313; type="text/xml"; start="0.urn:uuid:[email protected]"; charset="UTF-8"
      SOAPAction: "SendSubmissionReceipts"
      User-Agent: Jakarta Commons-HttpClient/3.1
      Host: foo.bar.com
      Cookie: $Version=0; JSESSIONID=0001JGVZICF0ATPGIDRKW5J1LHY:11p9fo6l7; $Path=/
      Content-Length: 3978
       
      <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header>[contents intentionally omitted]</soapenv:Header><soapenv:Body>[contents intentionally omitted]</soapenv:Body></soapenv:Envelope>

      Correct overall content-type and boundary value, but no attachment parts and no boundaries.

      The problem may be in CommonsHttpConnection.onSendAfterWrite() where a ByteArrayRequestEntity is always used instead of the MultipartRequestEntity that the Commons HttpClient API says should be used for requests with attachments

      protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
        postMethod.setRequestEntity(new ByteArrayRequestEntity(requestBuffer.toByteArray()));
        requestBuffer = null;
        httpClient.executeMethod(postMethod);
      }

      It would seem to me that onSendAfterWrite() should be checking the WebServiceMessage to see if there are any attachments, and if there are, creating the necessary xml message and attachment Parts and passing them to a MultipartRequestEntity instead of sending the entire request to a ByteArrayRequestEntity.

        Activity

        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        I don't think a MultipartRequestEntity is applicable for SOAP attachments, because that sets the content type to "multipart/form-data", while SOAP needs "multipart/related".

        I will investigate this bug for 1.5.3.

        Show
        arjen.poutsma Arjen Poutsma added a comment - I don't think a MultipartRequestEntity is applicable for SOAP attachments, because that sets the content type to "multipart/form-data", while SOAP needs "multipart/related". I will investigate this bug for 1.5.3.
        Hide
        barsimp47 Barry Simpson added a comment -

        I've tried creating a workaround using MultipartRequestEntity, and it does unfortunately set the message parts' content-types to "multipart/form-data", even though I specifically told it to use a different content-type using Part.setContentType() on each Part. ("text/xml" for the actual SOAP message, and "application/octet-stream" for my attachment, which happens to be a zip archive. "application/octet-stream" is what the service is expecting for some reason.)

        The overall HTTP message's Content-Type header is correctly set to "multipart/related", but I don't want the individual parts to be "multipart/related". I want the parts to be what I tell them to be with Part.setContentType().

        Show
        barsimp47 Barry Simpson added a comment - I've tried creating a workaround using MultipartRequestEntity, and it does unfortunately set the message parts' content-types to "multipart/form-data", even though I specifically told it to use a different content-type using Part.setContentType() on each Part. ("text/xml" for the actual SOAP message, and "application/octet-stream" for my attachment, which happens to be a zip archive. "application/octet-stream" is what the service is expecting for some reason.) The overall HTTP message's Content-Type header is correctly set to "multipart/related", but I don't want the individual parts to be "multipart/related". I want the parts to be what I tell them to be with Part.setContentType().
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        Interesting.

        Could you also try to use the HttpUrlConnectionMessageSender? I would like to know if this is a Commons Http Client specific bug or not.

        Show
        arjen.poutsma Arjen Poutsma added a comment - Interesting. Could you also try to use the HttpUrlConnectionMessageSender? I would like to know if this is a Commons Http Client specific bug or not.
        Hide
        barsimp47 Barry Simpson added a comment -

        Doesn't seem to be working with HttpUrlConnectionMessageSender either, though I can't see the exact HTTP messages because I don't know how to make the HttpUrlConnection log its requests and responses like I can with Commons HttpClient.

        I'm getting the same error response from the service I'm trying to access, so I'm assuming the HTTP message is still being packaged incorrectly.

        Show
        barsimp47 Barry Simpson added a comment - Doesn't seem to be working with HttpUrlConnectionMessageSender either, though I can't see the exact HTTP messages because I don't know how to make the HttpUrlConnection log its requests and responses like I can with Commons HttpClient. I'm getting the same error response from the service I'm trying to access, so I'm assuming the HTTP message is still being packaged incorrectly.
        Hide
        barsimp47 Barry Simpson added a comment -

        But that's without my custom MessageSender workaround code which tries to add the attachment parts. So I suppose I'll check into that next: how to add attachments to HttpUrlConnection POST messages.

        Show
        barsimp47 Barry Simpson added a comment - But that's without my custom MessageSender workaround code which tries to add the attachment parts. So I suppose I'll check into that next: how to add attachments to HttpUrlConnection POST messages.
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        I've written a test, and it fails for Axiom, but not for SAAJ. So as a (temporary) workaround, you can use SAAJ.

        Show
        arjen.poutsma Arjen Poutsma added a comment - I've written a test, and it fails for Axiom, but not for SAAJ. So as a (temporary) workaround, you can use SAAJ.
        Hide
        barsimp47 Barry Simpson added a comment -

        Yes, it is working for me with SAAJ too. Thanks.

        Show
        barsimp47 Barry Simpson added a comment - Yes, it is working for me with SAAJ too. Thanks.
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        Unfortunately, Axiom's SwA attachment support seems broken. I've written a mail about this to the Axiom dev list, so we'll see what happens.

        Show
        arjen.poutsma Arjen Poutsma added a comment - Unfortunately, Axiom's SwA attachment support seems broken. I've written a mail about this to the Axiom dev list, so we'll see what happens.
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        Turns out this wasn't an issue in Axiom, but rather in the combination of using Axiom and SAAJ in the same JVM. See https://saaj.dev.java.net/servlets/ReadMsg?list=users&msgNo=83.

        At any rate, I fixed it, so it works now.

        Show
        arjen.poutsma Arjen Poutsma added a comment - Turns out this wasn't an issue in Axiom, but rather in the combination of using Axiom and SAAJ in the same JVM. See https://saaj.dev.java.net/servlets/ReadMsg?list=users&msgNo=83 . At any rate, I fixed it, so it works now.
        Hide
        montebove Luciano Montebove added a comment -

        With 1.5.3 I still have a java.io.IOException: Invalid content type "text/xml; charset=UTF-8" for XmlDCH
        using Axiom and SwA when in the same JVM I call a Spring Web Service using SAAJ and MTOM.
        The Axiom /SwA service works fine until I call the SAAJ/MTOM service then stop working .

        Show
        montebove Luciano Montebove added a comment - With 1.5.3 I still have a java.io.IOException: Invalid content type "text/xml; charset=UTF-8" for XmlDCH using Axiom and SwA when in the same JVM I call a Spring Web Service using SAAJ and MTOM. The Axiom /SwA service works fine until I call the SAAJ/MTOM service then stop working .
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        When I said "I fixed it", I meant that Axiom SwA support now works. However, that bug in the XmlDCH is not something I can solve, I has to be solved in SAAJ. The current SAAJ CVS contains my fix, but I have no idea when this will be out.

        However, see that saaj mailing list thread for a workaround.

        Show
        arjen.poutsma Arjen Poutsma added a comment - When I said "I fixed it", I meant that Axiom SwA support now works. However, that bug in the XmlDCH is not something I can solve, I has to be solved in SAAJ. The current SAAJ CVS contains my fix, but I have no idea when this will be out. However, see that saaj mailing list thread for a workaround.
        Hide
        montebove Luciano Montebove added a comment -

        Thanks, your workaround:
        CommandMap.setDefaultCommandMap(new MailcapCommandMap());
        before adding an attachment with Axiom seems to work.
        But as in tje last night build of Metro 1.3 they released the patched SAAJ as stated here https://saaj.dev.java.net/issues/show_bug.cgi?id=32
        I extracted the new SAAJ from there and used it with Java 5 and surprise they solved an exception but there was another behind the corner, now I get this exception(if I comment out your workaround code line):

        23:09:25,187 ERROR [STDERR] Caused by: java.io.IOException: Unable to run the JAXP transformer on a stream java.lang.String
        23:09:25,187 ERROR [STDERR] at com.sun.xml.messaging.saaj.soap.XmlDataContentHandler.writeTo(XmlDataContentHandler.java:151)
        23:09:25,187 ERROR [STDERR] at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:897)
        23:09:25,187 ERROR [STDERR] at javax.activation.DataHandler.writeTo(DataHandler.java:330)
        23:09:25,187 ERROR [STDERR] at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403)
        23:09:25,187 ERROR [STDERR] at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:874)
        23:09:25,187 ERROR [STDERR] at org.apache.axiom.om.impl.MIMEOutputUtils.writeBodyPart(MIMEOutputUtils.java:245)
        23:09:25,187 ERROR [STDERR] at org.apache.axiom.om.impl.MIMEOutputUtils.writeSOAPWithAttachmentsMessage(MIMEOutputUtils.java:283)

        Show
        montebove Luciano Montebove added a comment - Thanks, your workaround: CommandMap.setDefaultCommandMap(new MailcapCommandMap()); before adding an attachment with Axiom seems to work. But as in tje last night build of Metro 1.3 they released the patched SAAJ as stated here https://saaj.dev.java.net/issues/show_bug.cgi?id=32 I extracted the new SAAJ from there and used it with Java 5 and surprise they solved an exception but there was another behind the corner, now I get this exception(if I comment out your workaround code line): 23:09:25,187 ERROR [STDERR] Caused by: java.io.IOException: Unable to run the JAXP transformer on a stream java.lang.String 23:09:25,187 ERROR [STDERR] at com.sun.xml.messaging.saaj.soap.XmlDataContentHandler.writeTo(XmlDataContentHandler.java:151) 23:09:25,187 ERROR [STDERR] at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:897) 23:09:25,187 ERROR [STDERR] at javax.activation.DataHandler.writeTo(DataHandler.java:330) 23:09:25,187 ERROR [STDERR] at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403) 23:09:25,187 ERROR [STDERR] at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:874) 23:09:25,187 ERROR [STDERR] at org.apache.axiom.om.impl.MIMEOutputUtils.writeBodyPart(MIMEOutputUtils.java:245) 23:09:25,187 ERROR [STDERR] at org.apache.axiom.om.impl.MIMEOutputUtils.writeSOAPWithAttachmentsMessage(MIMEOutputUtils.java:283)
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        I would suggest that you mention that on the SAAJ mailing list.

        Show
        arjen.poutsma Arjen Poutsma added a comment - I would suggest that you mention that on the SAAJ mailing list.
        Hide
        montebove Luciano Montebove added a comment -
        Show
        montebove Luciano Montebove added a comment - Done with a possible patch: https://saaj.dev.java.net/servlets/ReadMsg?list=users&msgNo=90
        Hide
        montebove Luciano Montebove added a comment -

        My fix was incorporated in last SAAJ build:
        https://saaj.dev.java.net/servlets/ReadMsg?list=users&msgNo=93
        https://saaj.dev.java.net/servlets/ProjectDocumentList

        I tested with my Spring Web Services applications using both Axiom and SAAJ in the same JVM (Java 5) and all works fine now.

        Show
        montebove Luciano Montebove added a comment - My fix was incorporated in last SAAJ build: https://saaj.dev.java.net/servlets/ReadMsg?list=users&msgNo=93 https://saaj.dev.java.net/servlets/ProjectDocumentList I tested with my Spring Web Services applications using both Axiom and SAAJ in the same JVM (Java 5) and all works fine now.
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        Great. Open source works!

        Show
        arjen.poutsma Arjen Poutsma added a comment - Great. Open source works!
        Hide
        arjen.poutsma Arjen Poutsma added a comment -

        Closing issues in 1.5.3

        Show
        arjen.poutsma Arjen Poutsma added a comment - Closing issues in 1.5.3

          People

          • Assignee:
            arjen.poutsma Arjen Poutsma
            Reporter:
            barsimp47 Barry Simpson
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: