2 Replies Latest reply on Apr 21, 2011 10:25 AM by romanws

    Soap Attachment causes OutOfMemoryError

    s3filho

      Hello Everyone,

      I am building a Web Services that will receive a file attachment in its message.
      I used the DataHandler classe and the specified annotations (@XmlAttachmentRef) and it worked prety fine.

      The problem is that when the file to be transmited is really big (more than 100MB, for example) the Client throws an
      java.lang.OutOfMemoryError, and I belive it does that before even start sending the message.

      My Client code is:

      SignerService service = new SignerService();
      Signer signer = service.getSignerPort();
      
      BindingProvider bp = (BindingProvider)signer;
      Binding binding = bp.getBinding();
      ((SOAPBinding)binding).setMTOMEnabled(true);
      
      String path = "..."; //My file path
      
      MyDocument doc = new MyDocument();
      FileDataSource dataSource = new FileDataSource(path);
      doc.setDataHandler(new DataHandler(dataSource));
      
      signer.sendDoc(doc);
      


      Where MyDocument is:
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "myDocument", propOrder = {
       "dataHandler"
      })
      public class MyDocument {
      
       @XmlElement(type = String.class)
       @XmlAttachmentRef
       protected DataHandler dataHandler;
      
       public DataHandler getDataHandler() {
       return dataHandler;
       }
       public void setDataHandler(DataHandler value) {
       this.dataHandler = value;
       }
      }
      


      The stack trace is:
      Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
       at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:95)
       at sun.net.www.http.PosterOutputStream.write(PosterOutputStream.java:61)
       at javax.activation.DataHandler.writeTo(DataHandler.java:308)
       at com.sun.xml.ws.message.DataHandlerAttachment.writeTo(DataHandlerAttachment.java:110)
       at com.sun.xml.ws.encoding.MtomCodec.writeAttachments(MtomCodec.java:216)
       at com.sun.xml.ws.encoding.MtomCodec.encode(MtomCodec.java:167)
       at com.sun.xml.ws.encoding.SOAPBindingCodec.encode(SOAPBindingCodec.java:258)
       at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:142)
       at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:86)
       at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
       at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
       at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
       at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
       at com.sun.xml.ws.client.Stub.process(Stub.java:248)
       at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
       at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
       at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
       at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
       at $Proxy29.sendDoc(Unknown Source)
       ...
      


      Increasing the Java heap space of Client (to 256MB) does resolve the problem for that file but if I try sending a bigger file
      (500MB) the Error comes back. Since I can't limit a file size to my system, increasing the heap space is only a workaround.

      It seems that the whole file is being loaded into the memory heap and I though DataHandler class and MTMO property were to address this memory problem, by using cache and flushing routines.

      Is there anyway to assure that my file will be sent regardless of its size?


      Thank you very much