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