Skip to content

fix: resolve Windows fill template copy failures (#1021) - #1034

Open
Mikkey-f wants to merge 4 commits into
apache:mainfrom
Mikkey-f:fix/1021-windows-fill-template
Open

fix: resolve Windows fill template copy failures (#1021)#1034
Mikkey-f wants to merge 4 commits into
apache:mainfrom
Mikkey-f:fix/1021-windows-fill-template

Conversation

@Mikkey-f

Copy link
Copy Markdown

What and why

Fixes the Copy template failure errors that the fill examples
(FillBasicExample, FillComplexExample) hit on Windows. Two root causes:

1. WriteWorkbookHolder leaks the output stream it opens when initialization fails

The constructor opens a FileOutputStream for the target file before copying
the template. When the copy fails (or any later initialization step throws),
the stream was never closed — the file stays locked on Windows. Unix lets you
delete an open file, which is why CI stayed green. This is a cross-platform
resource leak; Windows just surfaces it first.

Fix: wrap initHandler + copyTemplate so the stream opened by the holder is
closed before the exception propagates. Caller-provided streams are untouched —
ownership stays with the caller.

2. ExampleFileUtil returns the percent-encoded URL path

URL.getPath() does not decode. On Windows, template file names built with
File.separator (\) are encoded as %5C in the resource URL, so the returned
path pointed at a file literally named templates%5Clist.xlsx — which does not
exist → Copy template failure. On Unix the separator / needs no encoding,
which is why CI passed.

Fix: decode via URL.toURI() in a shared toFilePath helper. This also fixes
paths containing spaces or other reserved characters (%20 etc.).

Tests

  • New WriteWorkbookHolderOutputStreamTest (2 cases): the stream opened by the
    holder is closed on init failure (on Windows an open stream locks the file, so
    deletion fails without the fix); caller-provided streams are not closed.
  • The fill ITCases (FillBasicExampleITCase, FillComplexExampleITCase) now
    pass on Windows; they previously failed with Copy template failure.
  • Full module suite green: 846 tests, 0 failures (fesod-common / fesod-shaded /
    fesod-sheet / fesod-sheet-examples), spotless:check and javadoc:javadoc pass.

Closes #1021

…1021)

The constructor opens the output file stream before copying the template.
If initialization fails (e.g. missing template), the stream was never
closed, leaving the target file locked on Windows. Close streams opened
by the holder on failure; caller-provided streams remain the caller's
responsibility.
…1021)

URL.getPath() returns the encoded path. On Windows, template file names
built with File.separator ('\') are percent-encoded as %5C in the
resource URL, so the returned path pointed at a non-existent file and
fill examples failed with 'Copy template failure'. Decode via
URL.toURI() instead.
initHandler(writeWorkbook, null);
copyTemplate();
} catch (IOException e) {
closeOutputStreamIfOwned();

@delei delei Aug 23, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we gate closeOutputStreamIfOwned() with autoCloseStream instead of file != null?

autoCloseStream is more consistent with existing close behavior (while still not closing caller-provided streams).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion — updated. The failure path in WriteWorkbookHolder now gates the close on autoCloseStream instead of file != null, which mirrors the success-path behavior. Callers using autoCloseStream(false) keep their streams unclosed on failure as well, and the test now sets autoCloseStream(false) explicitly to assert that contract.

@delei delei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Fill tests fail on Windows: output stream leak on CSV+template exception, and URL.getPath() breaks example templates

2 participants