On Mar 17, 2009, at 2:30 PM, Paul Sandoz wrote:
>
> On Mar 16, 2009, at 3:07 PM, Craig McClanahan wrote:
>
>> Paul Sandoz wrote:
>>> Hi,
>>>
>>> When using jersey-multipart we are getting out of memory issues
>>> because JavaMail buffers [1].
>>>
>>> I have been looking at the MIMEPull API [2]. It is a clean and
>>> simple API that supports pull-based streaming of body parts (if
>>> accessed in the serialized order) or buffering to disk.
>>>
>>> Craig has also proposed using Mime4J [3]. This API is a push-
>>> based streaming API, e.g. like SAX where as MIMEPull is like StAX.
>>> The last stable release of Mime4j is version 0.6
>>>
>>> From a quick look at both APIs i prefer the pull model of MIMEPull
>>> rather than the push model of Mime4J. The former makes it much
>>> easier to integrate into the existing code base.
>>>
>>> In addition to switching from JavaMail for parsing i propose that
>>> while we do that work we implement support for @FormDataParam for
>>> getting access to MIME body parts and deprecate the use of
>>> @FormParam.
>>>
>> I agree with your preference and the suggested approach. Pull will
>> definitely be easier to work with.
>>
>
> I have started work on this. Which has led to an "interesting" bug
> with the Client API not pushing out the correct content type set by
> the multipart writer (it looks like JavaMail is very forgiving when
> parsing where as MIMEPull requires a boundary string).
>
I have just committed the following:
- Switched from JavaMail to MIMEPull. I changed the constructor of
BodyPartEntity to take a MIMEPart instance.
Because MIMEPull caches to disk the code of BodyPartEntity is now
simplified. I decided to retain
BodyPartEntity just in case we need to make changes to the
underlying MIME implementation in the future.
- The MultiPartReader now uses the CloseableService, available on the
server-side. Instances of MultiPart
are added and are closed when the request goes out of scope. So
there is no need for developers to
explicitly call "cleanup".
- It is now possible to directly return a MultiPart instance that was
obtained as a request entity,
for example:
@Consumes("multipart/mixed")
@Produces("multipart/mixed")
public MultiPart twelve(MultiPart multiPart) {
return multiPart;
}
Next steps:
- we should probably bump up the default in-memory threshold size from
4K. MIMEPull has a much higher
default value, 1 meg, per attachment.
- Support @FormDataParam.
Paul.