Document constructor using ByteArrayInputStream results in document with no content

Using Words for Java 20.12.
Given a docx document with 1 word in it, converted to a byte array by existing code, and then to a ByteArrayInputStream…
Calling new Document(stream) and then document.save(path) the resulting document no longer contains any content.
If I pass my original inputStream unchanged back to existing code, a correct Word doc is output elsewhere in the app.

minimal example

private void testSave(byte[] docByteArray) {
	ByteArrayInputStream inputStream = new ByteArrayInputStream(docByteArray);

	// construct Aspose doc & add our custom property
	Document asposeDoc = new Document(inputStream);
	inputStream.close();
	// the doc that is saved to disk is missing all content
	asposeDoc.save("C:\\DEV\\asposeDocTest\\demo.docx");
}

The intention is to insert some CustomDocumentProperties and then save the Document back to an outputStream to continue on to existing code. If I continue with the exercise, the byte[] from outputStream.toByteArray() is only about half the size it should be

a full example of what is intended:

private byte[] embedDocIdIntoWordDocument(byte[] docByteArray) {
	ByteArrayInputStream inputStream = new ByteArrayInputStream(docByteArray);
	try {
		FileFormatInfo info = FileFormatUtil.detectFileFormat(inputStream);
		int loadingFileFormat = info.getLoadFormat();

		// construct Aspose doc
		Document asposeDoc = new Document(inputStream);
		inputStream.close();

        // add some custom props
        //CustomDocumentProperties propsCustom = asposeDoc.getCustomDocumentProperties();
        //propsCustom.add("foo", "bar");

		// turn Aspose doc back into a byte array since that's what downstream expects
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		asposeDoc.save(outputStream, FileFormatUtil.loadFormatToSaveFormat(loadingFileFormat));
		outputStream.close();
		return outputStream.toByteArray();
	} catch (Exception e) {
		throw new ServiceException(e.getMessage());
	}
}

The resulting output byte array is passed back to existing (working) code.
I do not have control over the input or the output as a byte array.

Please, oh please, what have I done wrong? I wonder if this is a bug… Please read on…

Additionally If I have access to a Spring MultipartFile and I construct my Document using the inputStream I can save the resulting document to disk ok

private DocumentDTO savingFromAMultipartFile(MultipartFile file) {
	Document asposeDoc = new Document(file.getInputStream());
	// write to disk. This document is OK
	asposeDoc.save("C:\\DEV\\asposeDocTest\\demoMFDM.docx");
}

So the only difference is using an InputStream constructed from a byte array vs using one from a form submission.

Any advice is welcome.

(apparently I can’t attach my example docx file. But all I did was open Word, type “Jan6”, and save it)

@jm.ln.com,

After an initial test with the licensed latest (21.1) version of Aspose.Words for Java, we were unable to reproduce this issue on our end. We used the following simple Java code for testing on our end:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

Document doc = new Document("C:\\Temp\\word.docx");
doc.save(baos, SaveFormat.DOCX);

byte[] docByteArray = baos.toByteArray();

testSave(docByteArray); 

public static void testSave(byte[] docByteArray) throws Exception {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(docByteArray);

    // construct Aspose doc & add our custom property
    Document asposeDoc = new Document(inputStream);
    inputStream.close();
    // the doc that is saved to disk is missing all content
    asposeDoc.save("C:\\Temp\\21.1.docx");
}

Also, can you please try using the following method and see how it goes on your end. I just added ByteArrayInputStream.reset() method after int loadingFileFormat = info.getLoadFormat();

private static byte[] embedDocIdIntoWordDocument(byte[] docByteArray) {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(docByteArray);
    try {
        FileFormatInfo info = FileFormatUtil.detectFileFormat(inputStream);
        int loadingFileFormat = info.getLoadFormat();

        inputStream.reset();

        // construct Aspose doc
        Document asposeDoc = new Document(inputStream);
        inputStream.close();

        // add some custom props
        //CustomDocumentProperties propsCustom = asposeDoc.getCustomDocumentProperties();
        //propsCustom.add("foo", "bar");

        // turn Aspose doc back into a byte array since that's what downstream expects
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        asposeDoc.save(outputStream, FileFormatUtil.loadFormatToSaveFormat(loadingFileFormat));
        outputStream.close();
        return outputStream.toByteArray();
    } catch (Exception e) {
        // throw new ServiceException(e.getMessage());
    }
    return null;
}

Grrrr. It’s right there in the docs for FileFormatUtil “When this method returns, the stream is positioned at the end of the document.” Somehow I missed that.

Thanks so much for the suggestion on inputStream.reset(). I just couldn’t see it.