pentaho/pentaho-kettle · error · IOException

Already closed

Error message

Already closed

What it means

JCRFileOutputStream.close writes the buffered data to the repository via client.writeData. If close() is invoked a second time after the stream was already closed, it throws an IOException wrapping an IllegalStateException('Already closed'). This guards against double-write of the stream's buffer to the repository.

Solutions

  1. Remove duplicate close() calls; rely on a single close path (prefer try-with-resources alone)
  2. Check the stream's own guard if you must double-close defensively
  3. Wrap close() in an ignored-IOException guard only when the close is best-effort

Example fix

// before
stream.close();
...
stream.close(); // second close throws 'Already closed'
// after
stream.close();
...
if ( !stream.isClosed() ) { stream.close(); } // or remove the duplicate close entirely
Defensive patterns

Strategy: try-catch

Validate before calling

// guard before closing defensively
boolean streamIsOpen( OutputStream s ) { return s != null && !( s instanceof JCRFileOutputStream j && j.isClosed() ); }

Type guard

boolean canClose( OutputStream s ) {
  return s instanceof JCRFileOutputStream && !((JCRFileOutputStream) s).isClosed();
}

Try / catch

try ( OutputStream out = client.getOutputStream( name ) ) {
  out.write( data );
} catch ( IOException e ) {
  if ( e.getCause() instanceof IllegalStateException
       && "Already closed".equals( e.getCause().getMessage() ) ) {
    log.debug( "Stream already closed; ignoring" );
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling close() twice on the same JCRFileOutputStream, or code paths (e.g. try-with-resources plus an explicit close in a finally block) that close the stream more than once.

Common situations: try-with-resources combined with a manual close(); utility code that closes streams defensively; reusing a cached output stream reference after it has been committed.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/20643dca940221f1. Report an issue: GitHub.

Appendix: source

Thrown at plugins/repo-vfs/repo-vfs-ws/src/main/java/org/pentaho/di/plugins/repovfs/ws/vfs/JCRFileOutputStream.java:44

 */
public class JCRFileOutputStream extends ByteArrayOutputStream {

  private static final Logger log = LoggerFactory.getLogger( JCRFileOutputStream.class );

  private final RepositoryClient client;
  private final String[] name;

  private boolean closed = false;

  public JCRFileOutputStream( String[] fileName, RepositoryClient client ) {
    this.name = fileName;
    this.client = client;
  }

  @Override
  public void close() throws IOException {
    if ( closed ) {
      throw new IOException( new IllegalStateException( "Already closed" ) );
    }

    closed = true;
    try ( ByteArrayInputStream bais = new ByteArrayInputStream( toByteArray() ) ) {
      client.writeData( name, bais );
      log.debug( "data written" );
    } catch ( RepositoryClientException e ) {
      throw new IOException( e );
    }
  }

}

View on GitHub (pinned to f3058517a1)