While dealing with a javax.imageio.IIOException: Can't create an ImageInputStream! after calling ImageIO.read(File file) because of a missing FileImageInputStreamSpi provider I recognized that the ImageIO service providers being available in my webapp depends on the fact whether a Geoserver (http://geoserver.org) webapp is running in the same Tomcat web container or not:
Only my webapp running:
My webapp running along Geoserver 2.15.0 webapp:
Code in my webapp:
IIORegistry reg = IIORegistry.getDefaultInstance();
Iterator<ImageInputStreamSpi> it = reg.getServiceProviders(ImageInputStreamSpi.class, true);
while (it.hasNext()) {
ImageInputStreamSpi spi = it.next();
System.out.println(spi.getDescription(Locale.GERMAN));
}
I'm using Tomcat 9.0.16 webapp and OpenJDK 11.
I wonder why both webapps may interfere in this way - isn't it actually a security issue?
Thank you for some general clarification.
It's a known issue with ImageIO
and the IIORegistry
. The registry instance is shared between all applications across the VM. And this often causes problems, like in your case.
I've written a little about Deploying ImageIO plugins in a Web App in the readme for the TwelveMonkeys ImageIO project. Using the context listener may help with some problems, but it does not fix the underlying problem.
Another fix, is to deploy ImageIO plugins only as part of the server itself (ie. shared lib folder), to make sure all web apps sees the same plugins.
If you look deep in the source code of IIORegistry
you'll see that it actually has some support for multiple registries, but these are tied to AppContext
s (used by applets, webstart etc), which unfortunately is not the same as a web application context. It does seem like it should be possible to make the web contexts have different AppContext
s too, if only they used different ThreadGroup
s. But I have never found a way to make an app server assign a different thread group to each web application context.