Bug 64879 - SXSSFSheet dispose() fails to remove Temporary files for java.io.IOException: No space left on device
Summary: SXSSFSheet dispose() fails to remove Temporary files for java.io.IOException:...
Status: RESOLVED FIXED
Alias: None
Product: POI
Classification: Unclassified
Component: SXSSF (show other bugs)
Version: 4.1.2-FINAL
Hardware: All All
: P2 major (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-11-07 00:01 UTC by Shawn Boyce
Modified: 2020-11-07 10:49 UTC (History)
0 users



Attachments
Exception stack trace (241.39 KB, image/png)
2020-11-07 00:01 UTC, Shawn Boyce
Details
SXSSFSheet patch (927 bytes, patch)
2020-11-07 00:26 UTC, Shawn Boyce
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Shawn Boyce 2020-11-07 00:01:48 UTC
Created attachment 37549 [details]
Exception stack trace

The SXSSFSheet has a bug where it will fail to delete the temporary file it has created when the file system runs out of space. 

I found this problem when creating a very large excel workbook using SXSSFWorkbook. Attempting to write a new row fails (no space left), my code then attempts to cleanup by calling dispose(). This fails because the workbook attempts to flush before disposing and the flush fails with same IOException (no space left). The large amount of disk space consumed by the temporary file is only freed up when the program exits. I have attached a screenshot with the stack trace.

Here is the code in question (poi-ooxml-4.1.2)

https://github.com/apache/poi/blob/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java#L1910

    boolean dispose() throws IOException {
        if (!allFlushed) {
            flushRows();
        }
        return _writer.dispose();
    }

I suggest this be changed so that the writer.dispose() is always called.

    boolean dispose() throws IOException {
        try {
            if (!allFlushed) {
                flushRows();
            }
        } finally {
            return _writer.dispose();
        }
    }

Let me know if you have any more questions.
Comment 1 Shawn Boyce 2020-11-07 00:26:27 UTC
Created attachment 37550 [details]
SXSSFSheet patch
Comment 2 Shawn Boyce 2020-11-07 00:39:42 UTC
Attached Patch file with slight change from my original suggestion

    boolean dispose() throws IOException {
        boolean ret;
        try {
            if (!allFlushed) {
                flushRows();
            }
        } finally {
            ret = _writer == null || _writer.dispose();
        }
        return ret;
    }