2

In the

ImageIO.write(RenderedImage,String,File)

method, ImageOutputStream is created through

stream = createImageOutputStream(output);.

In the createImageOutputStream A runtime exception is caught and returns null from catch block.

try {
    iter = theRegistry.getServiceProviders(ImageOutputStreamSpi.class,true);
        } catch (IllegalArgumentException e) {
            return null;
        }

Can anyone help me understand:

  1. What is the reason behind catching a runtime exception here?(unless it is a crappy coding)
  2. On what condition, will the code throw illegal argument exception? (I dont see any reason for it to throw)

Please help.

Hirak
  • 3,601
  • 1
  • 22
  • 33
  • if `ImageOutputStreamSpi.class` wasnt added here, then `getServiceProviders` would throw. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/javax/imageio/spi/IIORegistry.java#IIORegistry.0initialCategories – goat May 30 '14 at 04:41
  • Why wouldn't it be added though? looks they are hardcoded inside a static block. – Hirak May 30 '14 at 05:27

1 Answers1

1

It could be a case of code that has evolved over time and no one cared to clean up, or it could be that the implementers of ImageIO relied on the contract of ServiceRegistry, rather than the implementation details of it. In the current implementation of ImageIO and ServiceRegistry I don't see how this could ever happen.

The only good thing I can see about it, is that you could now potentially change the implementation of IIORegistry or ServiceRegistry to do lazy loading of categories for example, or perhaps flush out categories with no Service Providers (Spi) present. The contracts of the methods would not break, and the ImageIO class would still work as it does.

Now, back to the question in your question, the answer is it should never throw NullPointerException. *

If you really want to, you could get stream to be null, by de-registering the Spi for File (FileImageOutputStreamSpi). But even then, a well-behaved ImageWriter should throw an IllegalStateException indicating that the output has not been set, not a NullPointerException (of course, programming errors could cause NPEs in other places, but this is not normal flow).

Update:

*) As the OP himself pointed out in the linked answer, throwing of NullPointerException can indeed happen if you pass a File object pointing to a non-existing path. This happens because the FileImageOutputStreamSpi "swallows" the IOException caused by the RandomAccessFile constructor (it does print the stacktrace to standard out), and returns null. In my opinion, this breaks the contract in a more severe way than it would by just letting the IOException bubble up, or wrapping it in an IllegalArgumentException with the original exception as cause and some explanatory message. Consider filing a bug report, if it doesn't already exist one for this issue.

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • Yes. there is no reason of getting NPE. But people are getting this exception so I was wondering why. e.g here...http://stackoverflow.com/questions/11153200/with-imageio-write-api-call-i-get-nullpointerexception?rq=1 – Hirak May 30 '14 at 11:09
  • @Hirak Weirdness... The contract (of `ImageOutputStreamSpi.createOutputStreamInstance(...)`) specifies that `IOException` can only be thrown if the *cache file is needed but cannot be created*. So it's stupid, but kind of correct. I think it should either throw `IOException` or `IllegalArgumentException` in this case, rather than returning `null`, but obviously someone thought otherwise. – Harald K May 30 '14 at 11:23
  • @Hirak Came to think of it, you could probably de-register the default `FileImageOutputStreamSpi` and replace it with your own that has the desired behavior (i.e. throws the exception as suggested above, instead of returning `null`). – Harald K May 30 '14 at 11:37
  • 1
    we could do that...I will try. So far I used the ImageIO.write which accepts a fileinputstream instead of file. that did it for me. – Hirak May 30 '14 at 11:44