<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hello all</p>
    <p>The <font face="monospace">ImageIO</font> class contains the
      following method (copying only relevant parts). The key point to
      notice is that any <font face="monospace">IOException</font> is
      assumed to be a problem with the cache file, never with the main
      output stream:</p>
    <p><br>
    </p>
    <blockquote>
      <pre>/**
 * …snip…
 * @return an {@code ImageOutputStream}, or {@code null}.
 * …snip…
 * @exception IOException if a cache file is needed but cannot be created.
 */
public static ImageOutputStream createImageOutputStream(Object output) throws IOException {
    // …snip…
    try {
        return spi.createOutputStreamInstance(output,
                                              usecache,
                                              getCacheDirectory());
    } catch (IOException e) {
        throw new IIOException("Can't create cache file!", e);
    }
    // …snip…
    return null;
}
</pre>
    </blockquote>
    <p><br>
    </p>
    <p>In the particular case where the output is a <font
        face="monospace">java.io.File</font>, the SPI implementation is
      as below (augmented with a copy of the Javadoc from public API).
      Note that the javadoc does not mention that <font
        face="monospace">ImageOutputStreamSpi.createOutputStreamInstance(…)</font>
      may return null.<br>
    </p>
    <p><br>
    </p>
    <blockquote>
      <pre>/**
 * …snip…
 * @return an {@code ImageOutputStream} instance.
 * …snip…
 * @exception IOException if a cache file is needed but cannot be created.
 */
public ImageOutputStream createOutputStreamInstance(…snip…) throws IOException {
    // …snip…
    try {
        return new FileImageOutputStream((File)output);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    // …snip…
}
</pre>
    </blockquote>
    <p><br>
    </p>
    <p>In case of failure to create the output stream, <font
        face="monospace">ImageIO.write(…)</font> throws an exception
      with the "Can't create an ImageOutputStream!" message, but we
      don't know why. The cause (for example no space left on device) is
      hidden in the <font face="monospace">System.err</font> outputs.
      If we replace the <font face="monospace">com.sun.imageio.spi.FileImageOutputStreamSpi</font>
      implementation by our own provider propagating the <font
        face="monospace">IOException</font> instead of returning null,
      it is slightly better but the exception is caught by <font
        face="monospace">ImageIO.createImageOutputStream</font> and
      rethrown with the misleading "Can't create cache file!" message.
      The consequence is that when writing millions of images (e.g.
      Earth Observation data) and the process fails somewhere at <font
        face="monospace">ImageOutputStream</font> creation time, it is
      currently difficult to identify the cause.</p>
    <p>Possible actions for improving the situation could be (from less
      disruptive to most disruptive):</p>
    <ul>
      <li>Replace the <font face="monospace">e.printStackTrace()</font>
        call by the use of logger.</li>
      <li>Remove the try … catch block in <font face="monospace">ImageIO.createImageOutputStream(…)</font>,
        so if an SPI choose to throw <font face="monospace">IOException</font>
        (at the cost of violating current Image I/O contract), <font
          face="monospace">ImageIO</font> does not misleadingly said
        that it is a problem with the cache.</li>
      <li>Modify <font face="monospace">ImageIO.createImageOutputStream(…)</font>
        contract by saying that <font face="monospace">IOException</font>
        may be thrown because of failure to create the main output
        stream, not only because of failure to create the cache file.
        Adapt <font face="monospace">FileImageOutputStreamSpi</font>
        implementation accordingly.<br>
      </li>
    </ul>
    <p>Is there any thought about what would be reasonable, what would
      be too much disruption?</p>
    <p>    Regards,</p>
    <p>        Martin</p>
    <p><br>
    </p>
  </body>
</html>