javax.imageio.IIOException: Can't create an ImageInputStream in Tomcat 9, OpenJDK 11 and Geoserver

user27772 :

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:

  • Service provider that instantiates a FileImageInputStream from a RandomAccessFile
  • Service provider that instantiates a FileImageInputStream from a File
  • Service provider that instantiates a FileCacheImageInputStream or MemoryCacheImageInputStream from an InputStream

My webapp running along Geoserver 2.15.0 webapp:

  • NIO Channel ImageInputStream
  • Service provider that wraps a FileImageInputStream
  • Service provider that helps connecting to the object pointed by a String
  • Service provider that helps connecting to the object pointed by a URL
  • Service provider that instantiates a FileImageInputStream from a RandomAccessFile

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.

haraldK :

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 AppContexts (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 AppContexts too, if only they used different ThreadGroups. But I have never found a way to make an app server assign a different thread group to each web application context.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=144377&siteId=1