Misleading message when using Image I/O for write operations

Martin Desruisseaux martin.desruisseaux at geomatys.com
Tue Sep 13 09:53:37 UTC 2022


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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/client-libs-dev/attachments/20220913/73871112/attachment.htm>


More information about the client-libs-dev mailing list