jdk/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java
changeset 36511 9d0388c6b336
parent 35667 ed476aba94de
child 40138 d294794a0878
--- a/jdk/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java	Tue Mar 15 13:48:26 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java	Thu Mar 17 19:04:16 2016 +0000
@@ -28,6 +28,9 @@
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
+import java.lang.reflect.Module;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Iterator;
 import javax.imageio.ImageReader;
@@ -587,8 +590,10 @@
             throw new IllegalArgumentException("Unsupported format name");
         }
         try {
-            Class<?> cls = Class.forName(formatClassName, true,
-                                      ClassLoader.getSystemClassLoader());
+            // Try to load from the same location as the module of the SPI
+            final String className = formatClassName;
+            PrivilegedAction<Class<?>> pa = () -> { return getMetadataFormatClass(className); };
+            Class<?> cls = AccessController.doPrivileged(pa);
             Method meth = cls.getMethod("getInstance");
             return (IIOMetadataFormat) meth.invoke(null);
         } catch (Exception e) {
@@ -598,4 +603,22 @@
             throw ex;
         }
     }
+
+    private Class<?> getMetadataFormatClass(String formatClassName) {
+        Module thisModule = ImageReaderWriterSpi.class.getModule();
+        Module targetModule = this.getClass().getModule();
+        Class<?> c = Class.forName(targetModule, formatClassName);
+        if (thisModule.equals(targetModule) || c == null) {
+            return c;
+        }
+        if (thisModule.isNamed()) {
+            int i = formatClassName.lastIndexOf(".");
+            String pn = i > 0 ? formatClassName.substring(0, i) : "";
+            if (!targetModule.isExported(pn, thisModule)) {
+                throw new IllegalStateException("Class " +  formatClassName +
+                  " in named module must be exported to java.desktop module.");
+            }
+        }
+        return c;
+    }
 }