ArrayIndexOutOfBoundsException when writing to PST file

Hello

I am using Aspose Java 24.1 and am busy trying to write around 60k emails to a newly created PST file. Initially, we are able to write a couple of thousand emails, but after some time, the below error is outputted over and over again each time a new message is being written to the PST file. Any idea on how to resolve this issue?

Caused by: java.lang.ArrayIndexOutOfBoundsException: arraycopy: last destination index 2147502080 out of bounds for byte[2147436544]
at com.aspose.email.system.io.MemoryStream.null write(null)(MemoryStream.java)
at com.aspose.email.zby.null a(null)(zby.java:83)
at com.aspose.email.NdbDoer$za.null a(null)(NdbDoer.java:4333)
at com.aspose.email.NdbDoer$za.null b(null)(NdbDoer.java:4428)
at com.aspose.email.NdbDoer$za.null a(null)(NdbDoer.java:4240)
at com.aspose.email.NdbDoer.null a(null)(NdbDoer.java:901)
at com.aspose.email.NdbDoer.null a(null)(NdbDoer.java:525)
at com.aspose.email.NdbDoer.null c(null)(NdbDoer.java:564)
at com.aspose.email.NdbDoer.null b(null)(NdbDoer.java:540)
at com.aspose.email.zbhq.null a(null)(zbhq.java:527)
at com.aspose.email.zaiw.null a(null)(zaiw.java:2419)
at com.aspose.email.zaiw.null a(null)(zaiw.java:923)
at com.aspose.email.zaxx.null a(null)(zaxx.java:1271)
at com.aspose.email.FolderInfo.null addMessage(null)(FolderInfo.java:885)
at com.stimulus.archiva.export.PSTExportFile.void exportBlob(com.stimulus.archiva.blob.Blob,com.aspose.email.MapiMessage)(PSTExportFile.java:163)

Hello @jamie-1 ,

Thank you for reporting your case.
To investigate the issue, we need some more information:

  • are these different messages or the same?
  • what is the size of the emails and the PST file?

They are different messages. The emails are regular emails that vary in size. Most should be around 70k-75k in size. The total number emails to export is 51050. The resultant file should be around 3.2GB. The write operation bombs out after processing 8761 emails.

The thing is its not like it bombs out on one large email, once the error occurs, no additional emails can be added to the PST.

@jamie-1
We have opened the following new ticket(s) in our internal issue tracking system.

Issue ID(s): EMAILJAVA-35257

Hello @jamie-1,

Based on your description, we have tested the issue but were unable to reproduce it.
Could you share the code sample you use to initialize a PersonalStorage and add messages?

Hello Sergey

Refer to attached class for an example of how we add messages to the PST file. I am aware that it is possible to use an iterator, however we haven’t changed it yet because the framework doesn’t allow it at the moment. Any recommendations / improvements / workarounds would be much appreciate.

PSTExportFile.zip (3.3 KB)

Hello @jamie-1,

Thank you for providing the code sample, we will investigate further.

Hello @jamie-1,

Writing a PST file is not a sequential data write, but multiple seek and overwrite.
Due to PST format during add message we need to seek to a previous position and overwrite.
Java OutputStream is not supported for seek and overwrite features and we can’t use it in PersonalStorage implementation without caching.
In case of PersonalStorage.create(OutputStream changes are cached to RAM and saved to the OutputStream after PersonalStorage close.

We can customize PST output stream that will work without overhead using Stream implementation:

PersonalStorage create(Stream stream..

CustomStream sample:

public class CustomStream extends Stream {...

// Gets the length of the stream in bytes
getLength()

// Gets the current position within the stream.
getPosition()

// Reads a block of bytes from the current stream and writes the data to a buffer
read(byte[] buffer, int offset, int count)

// Sets the position within the current stream to the specified value.
//   loc - seek reference point
//     Begin = 0
//     Current = 1
//     End = 2
seek(long offset, int loc)

// Writes a block of bytes to the current stream using data read from a buffer
write(byte[] buffer, int offset, int count)


PersonalStorage pstFile = PersonalStorage.create(new CustomStream(), FileFormatVersion.Unicode);

In case of PersonalStorage.create(“fileName” RandomAccessFile is used.
The RandomAccessFile supports seek and overwrite features and can be used without overhead.
The CustomStream implementation example based on java.nio.channels.FileChannel attached as
CustomStream.java (791 Bytes).

Also you can try to use the PST API, which is optimized for big PST files for OutputStream:

// blockSize - The optimal block size to expand cache buffer(in bytes)
// for example blockSize 10Mb = 10*1024*1024
PersonalStorage create(OutputStream stream, int blockSize, /*FileFormatVersion*/int version)