Bug 60102 - Improve error message when writing a document that has been closed
Summary: Improve error message when writing a document that has been closed
Status: REOPENED
Alias: None
Product: POI
Classification: Unclassified
Component: XWPF (show other bugs)
Version: 3.15-dev
Hardware: PC All
: P2 enhancement (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
: 59158 59559 59806 60967 61987 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-09-09 23:57 UTC by kenneth_lau
Modified: 2018-02-10 14:50 UTC (History)
5 users (show)



Attachments
Word docx file failed to write (14.30 KB, application/vnd.openxmlformats-officedocument.wordprocessingml.document)
2016-09-09 23:57 UTC, kenneth_lau
Details
Replace OpenXML4J return boolean with throws OpenXML4JException (24.57 KB, patch)
2016-09-10 23:30 UTC, Javen O'Neal
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description kenneth_lau 2016-09-09 23:57:39 UTC
Created attachment 34228 [details]
Word docx file failed to write

docx XWPFDocument opened from FileInputStream failed to write out to a new FileOutputStream

Here's the stacktrace --

org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Rule M2.4 exception : this error should NEVER happen! Please raise a bug at https://bz.apache.org/bugzilla/enter_bug.cgi?product=POI and attach a file that triggers it, thanks!
	at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.getContentType(ContentTypeManager.java:343)
	at org.apache.poi.openxml4j.opc.internal.ContentTypeManager.removeContentType(ContentTypeManager.java:256)
	at org.apache.poi.openxml4j.opc.OPCPackage.removePart(OPCPackage.java:958)
	at org.apache.poi.openxml4j.opc.PackagePart.getOutputStream(PackagePart.java:522)
	at org.apache.poi.xwpf.usermodel.XWPFDocument.commit(XWPFDocument.java:716)
	at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:464)
	at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:211)
Comment 1 Javen O'Neal 2016-09-10 05:51:27 UTC
I am unable to reproduce this in the latest nightly build of POI (r1755847).

Could you either check this against 3.15-beta2 or later a nightly, or produce a unit test that produces the error seen in comment 0?
Apache commons collections was recently added as a dependency and will need to be added to your class path.
https://builds.apache.org/job/POI/lastSuccessfulBuild/artifact/build/dist/

Here's my test case:

@Test
public void test60102() throws Exception {
    // read in from a java.io.File
    //XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("60102.docx");
    
    // or read in from a java.io.FileInputStream
    File infile = POIDataSamples.getDocumentInstance().getFile("60102.docx");
    InputStream fis = new FileInputStream(infile);
    XWPFDocument doc = new XWPFDocument(fis);
    
    // Write out to a file
    File outfile = TempFile.createTempFile("60102-resaved", "docx");
    OutputStream fos = new FileOutputStream(outfile);
    doc.write(fos);
    fos.close();
    
    // Write out to a byte array output stream
    XWPFDocument doc2 = XWPFTestDataSamples.writeOutAndReadBack(doc);
    doc2.close();
    
    doc.close();
}
Comment 2 kenneth_lau 2016-09-10 10:01:23 UTC
I've debugged into the issue further. The problem is reproduced after the OutputStream is closed by mistake after the first write.

Change test case test60102() to following --


// Write out to a file
    File outfile = TempFile.createTempFile("60102-resaved", "docx");
    OutputStream fos = new FileOutputStream(outfile);
    doc.write(fos);
    fos.close();
    doc.write(fos);


The second doc.write(fos) failed because OutputStream was closed by mistake.

The exception message was misleading. However, I've consider this is a usage error.
Comment 3 Javen O'Neal 2016-09-10 19:36:47 UTC
Throw IOException when writing a closed document implemented in r1760206
OutputStream out;
doc.close();
doc.write(out);

I have not yet implemented throwing an exception when writing an open document to a closed output stream.
OutputStream out;
out.close();
doc.write(out);
Comment 4 Javen O'Neal 2016-09-10 23:30:31 UTC
Created attachment 34231 [details]
Replace OpenXML4J return boolean with throws OpenXML4JException

(In reply to Javen O'Neal from comment #3)
> I have not yet implemented throwing an exception when writing an open
> document to a closed output stream.
> OutputStream out;
> out.close();
> doc.write(out);

To get this one closed, we're going to have to make quite a few changes to  methods in org.apache.poi.openxml4j.opc.internal.
These methods currently catch exceptions, occasionally log the error to the POILogger, and then return a boolean success value.
These will need to be replaced with void-returning functions that raise an exception. This will eliminate the need to check a return code, enable the POI logger, and check the logs.

A quick glance at the source code history reveals that the OpenXML4j classes have returned boolean success rather than throwing exceptions. Perhaps this is because this library originated from a C project rewritten in Java without replacing the C idioms with Java idioms.
https://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/DefaultMarshaller.java?revision=738842&view=markup#l41
Comment 5 Javen O'Neal 2016-09-27 15:57:43 UTC
*** Bug 59559 has been marked as a duplicate of this bug. ***
Comment 6 Javen O'Neal 2017-04-11 16:47:12 UTC
*** Bug 60967 has been marked as a duplicate of this bug. ***
Comment 7 Dominik Stadler 2018-02-08 19:50:27 UTC
*** Bug 61987 has been marked as a duplicate of this bug. ***
Comment 8 Alain Fagot Bearez 2018-02-10 14:48:21 UTC
*** Bug 59806 has been marked as a duplicate of this bug. ***
Comment 9 Alain Fagot Bearez 2018-02-10 14:50:27 UTC
*** Bug 59158 has been marked as a duplicate of this bug. ***