Hello all

The ImageIO class contains the following method (copying only relevant parts). The key point to notice is that any IOException is assumed to be a problem with the cache file, never with the main output stream:


   /**
     * …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;
   }


In the particular case where the output is a java.io.File, the SPI implementation is as below (augmented with a copy of the Javadoc from public API). Note that the javadoc does not mention that ImageOutputStreamSpi.createOutputStreamInstance(…) may return null.


   /**
     * …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…
   }


In case of failure to create the output stream, ImageIO.write(…) 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 System.err outputs. If we replace the com.sun.imageio.spi.FileImageOutputStreamSpi implementation by our own provider propagating the IOException instead of returning null, it is slightly better but the exception is caught by ImageIO.createImageOutputStream 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 ImageOutputStream creation time, it is currently difficult to identify the cause.

Possible actions for improving the situation could be (from less disruptive to most disruptive):

 * Replace the e.printStackTrace() call by the use of logger.
 * Remove the try … catch block in ImageIO.createImageOutputStream(…),
   so if an SPI choose to throw IOException (at the cost of violating
   current Image I/O contract), ImageIO does not misleadingly said that
   it is a problem with the cache.
 * Modify ImageIO.createImageOutputStream(…) contract by saying that
   IOException may be thrown because of failure to create the main
   output stream, not only because of failure to create the cache file.
   Adapt FileImageOutputStreamSpi implementation accordingly.

Is there any thought about what would be reasonable, what would be too much disruption?

    Regards,

        Martin

Reply via email to