Summary: | XSSFWorkbook#close() violates contract from Workbook#close() | ||
---|---|---|---|
Product: | POI | Reporter: | Michael <michael.holtermann> |
Component: | XSSF | Assignee: | POI Developers List <dev> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | hartmut_juergens, jbatchelor, lianyining, scorpdaddy.ch |
Priority: | P2 | ||
Version: | 3.14-FINAL | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | Linux | ||
Bug Depends on: | 59287 | ||
Bug Blocks: | 59678 | ||
Attachments: | TestCase demonstrating the issue |
In addition it's not possible to read from the workbook after it has been closed. A NPE will be thrown. For dicussion, the current javadoc for Workbook.close() is * Close the underlying input resource (File or Stream), * from which the Workbook was read. After closing, the * Workbook should no longer be used. * <p>This will have no effect newly created Workbooks. HSSFWorkbook.close() * Closes the underlying {@link NPOIFSFileSystem} from which * the Workbook was read, if any. Has no effect on Workbooks * opened from an InputStream, or newly created ones. XSSFWorkbook.close() * Closes the underlying {@link OPCPackage} from which this * document was read, if there is one We should probably rephrase those to state more in the order of "do not use at all after closing" and "it will close resources that have been passed in the constructor". This makes it as simple as possible and does not lead to very hard to find bugs if passed in resources are closed at some point. This way would also be consistent with what many other Java-Closeable-instances will do when they receive some resource themselves, e.g. see FileInputStreamReader, FileOutputStreamWriter, ... Sounds legit. I'd support that solution. *** Bug 59678 has been marked as a duplicate of this bug. *** The JavaDoc was partly updated in r1749213 and further refined in r1753912 to state that the close() call may also invalidate other things and should only be called before work with the object is done. I have also removed the "has no effect on newly created... ", as I don't think we should limit ourselves this way here, we should be able to do optimizations in the future which make use of this. All other Java Closables do it this way and thus let's do the same here. *** Bug 59356 has been marked as a duplicate of this bug. *** *** Bug 53613 has been marked as a duplicate of this bug. *** |
Created attachment 33890 [details] TestCase demonstrating the issue According to Workbook#close() it should not have any effect on newly created workbooks. This is true for HSSFWorkbooks. For XSSFWorkbooks it's not possible to write the document to an OutputStream after calling #close(). Since I'm mostly creating Workbooks from scratch, I thought I can call #close() just after creation of Worbook, instead of somewhere later when the document was written to outside world. Please see the attached test case that should demonstrate the issue. (Side note: The documentation states #close() will close the underlying input resource the Workbook was created from (e.g. calls to constructor HSSFWorkbook(InputStream)?). Shouldn't be the creator of that InputStream responsible for closing that Stream?) Regards, Michael