Details
Description
Using the Expander, I found that it will create a zip file that is not closed which results in an error message being written to std-err when garbage collection (and finalization) occurs.
I believe it is line 140 of the Expander as it creates a zip file that does not appear to be closed.
140: expand(new ZipFile(archive), targetDirectory);
I have created a test that demonstrates the behavior. It runs Expander.expand(file, file) followed by garbage collection and finalize, and passes if stderr was not written to.
Currently the test fails as "Cleaning up unclosed ZipFile for archive unknown archive" is written to stderr.
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.examples.Expander; import org.codehaus.plexus.util.StringUtils; import org.junit.jupiter.api.Test; import org.springframework.util.Assert; public class ExpanderCloseTest { @Test public void testExpanderClosesZipFile() { final ByteArrayOutputStream errOutputStream = new ByteArrayOutputStream(); try { final File sourceArchiveFile = createSampleZip(); final File targetExpansionDirectory = File.createTempFile("dest.zip", null); try (PrintStream ps = new PrintStream(errOutputStream, true, "UTF-8")) { System.setErr(ps); Expander expander = new Expander(); expander.expand(sourceArchiveFile, targetExpansionDirectory); System.gc(); System.runFinalization(); } } catch (Exception e) { throw new RuntimeException(e); } String stderr = new String(errOutputStream.toByteArray(), StandardCharsets.UTF_8); Assert.isTrue(StringUtils.isBlank(stderr), "Nothing should have been written to stderr, but this was: " + stderr); } private File createSampleZip() throws IOException, ArchiveException { final File sourceArchiveFile = File.createTempFile("example.zip", null); OutputStream archiveStream = new FileOutputStream(sourceArchiveFile); ArchiveOutputStream archive = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, archiveStream); archive.finish(); archiveStream.close(); return sourceArchiveFile; } }