tags:

views:

223

answers:

3

does java mail API uses streaming? where can i get the source code to confirm this. also i am tryign to send the mail using raw and non-raw mode. in raw mode i can pass an input Stream to MimeMessage constructor:[/b]

new MimeMessage(session, doc.getBodyInputStream());

In Non-raw mode, i have to do the following Since there can be any mime type, so i have to use DataHandler and DataSource. Since the DataSource interface contracts says of providing the fresh inputStream everytime we invoke getInputStream(), we need to keep the data in the byte[] which will throw OOM for large size or documents Is there a way to avoid this?

MimeMessage msg = new MimeMessage(session);
byte[] bArr = doc.getBody();
ByteArrayInputStream ins = new ByteArrayInputStream(
    bArr != null && bArr.length > 0 ?  bArr : "".getBytes());
msg.setDataHandler(new DataHandler( new ByteArrayDataSource(ins, mimeType)));
A: 

Regarding the OOM, in general your mails should not be larger than 10MB, which in turn should not be keeping more than 10MB in the byte array.

Is this a theoretical question? Or are you actually seeing this happen?

If you are seeing it happen, then increase your heap size, since the above code looks more or less correct.

Paul Wagland
A: 

Is it possible to dump the body to a (temporary) file, let the dumped bArr get out of scope (or set to null) and then use the FileDataSource?

extraneon
+1  A: 

Does the problem occur if you just process a single mail or do you get OOM after processing (and caching!) several mails?

Increasing heap size is an option, but if it just increases the time until you get hurt by the next OOM, then you think about alternatives to keeping the raw byte arrays in memory.

And you should use the ByteArrayDataSource(byte[] bArr, String type) constructor, this prevents from duplicating the complete byte array in memory, because the bArr is just stored in the DataSource as it is. The other constructor starts with an 8k byte array and doubles its size each time more space is needed - this wastes a lot of memory and may be the cause of your problem. (source)

Andreas_D
Ours is a B2B product providing this as one of the functionality and yes i understand ByteArrayDataSource(byte[] bArr, String type) will keep only one copy of byte[], but the client mail size is 1 Gig which will simply fail because we put data in memory instead of usign streaming.
Gaurav Abbi
But a ByteArrayDataSource will always store the byte array data in memory, and if it is created from an input stream, it will create (and resize) an internal byte array for the data. A 1 GByte mail? oh my god...
Andreas_D