Just to let you know, I was finally able to reproduce this, but it wasn't 
easy.    I added the SAAJ interceptor to our mtom test case and increased the 
data size to 250K, but I still couldn't reproduce the error in eclipse.   
However, when I ran mvn on the command line it failed, but not with Java 6, 
only Java 5.   I really have no idea why I cannot reliably reproduce it, 
especially in eclipse.  Doesn't matter what JDK I use in eclipse, I cannot 
reproduce it there.      Makes  debugging hard. 

In anycase, by adding a bunch of Thread.dumpStacks and printlns and such 
throughout the code, I THINK I've tracked down what is causing this.   I'll 
run some more tests and and get changes committed up today, I hope.    I 
mostly need to go through and remove all my dumpStacks and printlns now as 
well.  :-(

Dan

On Wed September 23 2009 7:11:56 pm K1001010 wrote:
> Thank you for the quick reply.  After hearing that the changes should be in
> 2.2.3 I dug further into my code and found a client-side interceptor which
> was causing all attachments to be cached.
> 
> I fixed that, and now see a server-side  problem when sending attachments.
> The server is using SSAJInInterceptor (via WSS4JInInterceptor) and on line
> 117 of the first there is this:
> 
>  for (Attachment a : atts) {
>      if (a.getDataHandler().getDataSource() instanceof
>  AttachmentDataSource) {
>           try {
> 
> ((AttachmentDataSource)a.getDataHandler().getDataSource()).cache();
> 
> 
> So the attachment is always being cached.  But more problematic is this:
> 
> After the above call the “inmem” flag of the CachedOutputStream is
>  correctly set to false.   By the time my application code calls
> CachedOutputStram.getInputStream() however, the flag is true, and hence an
> empty ByteArrayInputStream is returned.
> 
> Is there an apache CXF test case with MTOM enabled, WSS4JInInterceptor
>  used, and attachment larger than 64k?  The one I wrote seems to
>  consistently fail—the server side application code always getting a
>  non-null, but empty, stream, when the attachment is larger than 64k.
> 
> dkulp wrote:
> > On Wed September 16 2009 12:31:57 pm K1001010 wrote:
> >> Did these changes make it into the 2.2.3 release?
> >
> > It looks like it, yea.
> >
> >> I am testing with a 150MB attachment, and still see it being streamed to
> >> disk
> >
> > Hmm...   I hate to ask this as I don't want a 150MB test case, but is
> > there
> > any way you could create a "small" test case?
> >
> > There are a few cases where we do have to buffer it ahead of time.   If
> > there
> > are any SAAJ related things, we need to buffer.  Schema validation is
> > another.
> > If there are multiple attachments, it's likely the others may need to be
> > buffered, etc...   A testcase would help figure out what is going on.
> >
> > If you can debug it by setting a breakpoint in
> > org.apache.cxf.attachment.AttachementDataSource.cache() and determine why
> > cache is being called, that would also be helpful.
> >
> > Dan
> >
> >> I have this code:
> >>
> >>
> >> Picture picture = serviceProxy.getPictuer();
> >> DataHandler handler = picture.getImageData();
> >> InputStream is = handler.getInputStream();
> >>
> >>
> >> In version 2.2.2 the entire 150BM file would be streamed to temp file on
> >> line 3, which would return a file input stream (or a delegate too).
> >>
> >> In version 2.2.3 the entire 150MB file is streamed to temp file before
> >> line
> >> 1 returns.
> >>
> >> I disable schema validation using this system property:
> >>
> >> org.apache.spring.validation.mode=VALIDATION_NONE
> >>
> >> Is that correct?   Anything else required to stream directly from the
> >> wire?
> >>
> >> Thanks for any help.
> >>
> >> dkulp wrote:
> >> > Well, I THOUGHT this would have been easily doable, but when I
> >> > checked, it turns out the attachments were not streaming properly in
> >> > MTOM mode.
> >> >
> >> > :-(
> >> >
> >> > I've gone through and fixed a BUNCH of things related to the
> >> > attachment handling and streaming and such so some of this is now
> >> > possible.
> >> >
> >> > Now, with the latest code, when you get the DataSource, if at all
> >> > possible,
> >> > the input stream that is returned will properly be streaming off the
> >>
> >> wire
> >>
> >> > instead of cached.   Thus, you can copy directly from there to the
> >>
> >> output
> >>
> >> > stream.
> >> >
> >> > There are cases where this WON'T work stream directly, notably when
> >> > schema validation is turned on.   In that case, to work around issues
> >>
> >> in
> >>
> >> > JAXB, we buffer the content.     Also, if there are multiple
> >>
> >> attachments,
> >>
> >> > only the last
> >> > one can really be streamed this way.   The others get buffered.
> >> >
> >> > Dan
> >> >
> >> > On Mon July 27 2009 5:50:00 am dp-isp wrote:
> >> >> Hello everybody,
> >> >>
> >> >> We have a CXF webservice that is a kind of "repository service" and a
> >> >> webapp working as frontend for that repository.
> >> >> Those two components are on separate hosts.
> >> >>
> >> >> We would need to realize a continuous stream of data when downloading
> >> >> attachments from CXF webservice to the users' browser through the
> >> >> frontend
> >> >> webapp.
> >> >>
> >> >> The webapp is basically a servlet that invokes the webservice,
> >>
> >> receives
> >>
> >> >> the
> >> >> attachment datahandler and copies datahandler InputStream to servlet
> >> >> response OutputStream (servlet code is at the end of this email).
> >> >>
> >> >> Our issue: is it possible to directly link datahandler InputStream to
> >> >> servlet response OutputStream without re-building the whole
> >> >> attachment in memoroy or in a temporary file? (as can be configured
> >> >> by setting org.apache.cxf.io.CachedOutputStream.Threshold,
> >> >> org.apache.cxf.io.CachedOutputStream.OutputDirectory)
> >> >>
> >> >> Going more into details, is there a way to send to CXF the output
> >>
> >> buffer
> >>
> >> >> to
> >> >> write the attachment on? In such case we would send to CXF the
> >>
> >> sevlet's
> >>
> >> >> output buffer.
> >> >>
> >> >> Alternatively, is there a way to manage CXF working asynchronously
> >>
> >> with
> >>
> >> >> attachments, giving back control to the servlet before attachment
> >> >> downolad
> >> >> completion?
> >> >>
> >> >> Many thanks,
> >> >> Marco
> >> >>
> >> >> ---
> >> >>
> >> >> This is the servlet's involved code:
> >> >>
> >> >> ...
> >> >> StreamingService_Service ss = new StreamingService_Service(new
> >> >> URL(serviceURL));
> >> >> StreamingService port = ss.getServiceImplPort(new MTOMFeature());
> >> >>
> >> >> Resume myFile = port.downloadMethod(fileName, fileType, usr, pwd,
> >>
> >> repo);
> >>
> >> >> DataHandler handler = myFile.getResume();
> >> >>
> >> >> response.setHeader("Pragma", "No-cache");
> >> >> response.setContentType("application/octet-stream");
> >> >> response.setHeader("content-disposition", "attachment; filename=" +
> >> >> fileName + "." + fileType);
> >> >> try {
> >> >>         InputStream is = handler.getInputStream();
> >> >>         try {
> >> >>                 OutputStream os = response.getOutputStream();
> >> >>                 try {
> >> >>                         byte[] b = new byte[100000];
> >> >>                         int bytesRead = 0;
> >> >>                         while ((bytesRead = is.read(b)) != -1) {
> >> >>                                 os.write(b, 0, bytesRead);
> >> >>                         }
> >> >>                         System.out.println("Download del file " +
> >> >> myFile.getCandidateName()
> >>
> >> +
> >>
> >> >> "." + myFile.getResumeFileType() + " completato.");
> >> >>                 } finally {
> >> >>                         os.flush();
> >> >>                         os.close();
> >> >>                 }
> >> >>         } finally {
> >> >>                 is.close();
> >> >>         }
> >> >>
> >> >> } catch (Exception e) {
> >> >>         e.printStackTrace();
> >> >> }
> >> >> ...
> 

-- 
Daniel Kulp
[email protected]
http://www.dankulp.com/blog

Reply via email to