Skip to content

ScipWriter.close() / ScipOutputStream never closes the underlying OutputStream before Files.move(), leaking file descriptors and locking temp files on Windows #1066

Open

Description

@StrayCatDBA

Summary

In scip-aggregator, ScipWriter implements AutoCloseable and writes to a temporary file (tmp) via ScipOutputStream(new BufferedOutputStream(Files.newOutputStream(tmp))), then moves tmp to options.output() in ScipWriter.build().

However, ScipWriter.close() only calls output.flush(), and ScipOutputStream has no close() method at all. The underlying OutputStream to tmp is never closed before Files.move(tmp, options.output(), StandardCopyOption.REPLACE_EXISTING) runs.

Affected Code (main)

  • scip-aggregator/src/main/java/org/scip_code/scip_java/aggregator/ScipWriter.java (lines 20–40):
    this.output = new ScipOutputStream(new BufferedOutputStream(Files.newOutputStream(tmp)));
    ...
    public void build() throws IOException {
      close();
      Files.move(tmp, options.output(), StandardCopyOption.REPLACE_EXISTING);
    }
    
    @Override
    public void close() throws IOException {
      output.flush();
    }
  • scip-aggregator/src/main/java/org/scip_code/scip_java/aggregator/ScipOutputStream.java (lines 9–36):
    Wraps private final OutputStream out; and exposes write(...) and flush(), but does not implement AutoCloseable or provide a close() method.

Impact

  1. Windows (win32) file lock failures: When ScipWriter.build() calls Files.move(tmp, options.output(), StandardCopyOption.REPLACE_EXISTING) while the OutputStream handle on tmp is still open — especially when %TEMP% (e.g. C:\Users\...\AppData\Local\Temp) and --output (e.g. D:\workspace\index.scip or another mount/volume) are on different drives, forcing Files.move to copy + Files.delete(tmp) — Windows fails with:
    java.nio.file.FileSystemException: <tmp> -> <output>: The process cannot access the file because it is being used by another process
    
  2. Resource leak on all platforms: Every ScipWriter instance leaks an open file descriptor until GC/process exit.
  3. Note on Fix ScipWriter temp file creation on file systems without POSIX permissions #1049: Once Fix ScipWriter temp file creation on file systems without POSIX permissions #1049 fixes the PosixFilePermissions crash in ScipWriter on Windows, ScipWriter.build() immediately hits this unclosed stream during Files.move.

Suggested Fix

  1. Implement AutoCloseable (or add close()) on ScipOutputStream:
    public void close() throws IOException {
      flush();
      out.close();
    }
  2. Call output.close() in ScipWriter.close():
    @Override
    public void close() throws IOException {
      output.close();
    }

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions