< prev index next >

src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java

Print this page

        

@@ -21,24 +21,27 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
-package java.lang.module;
+package jdk.internal.module;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UncheckedIOException;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
 import java.net.URI;
 import java.net.URLConnection;
 import java.nio.ByteBuffer;
 import java.util.ArrayDeque;
 import java.util.Collections;
 import java.util.Deque;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Optional;

@@ -52,26 +55,22 @@
 import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
 import jdk.internal.jimage.ImageReaderFactory;
 import jdk.internal.misc.JavaNetUriAccess;
 import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.ModuleBootstrap;
-import jdk.internal.module.ModuleHashes;
 import jdk.internal.module.ModuleHashes.HashSupplier;
-import jdk.internal.module.SystemModules;
-import jdk.internal.module.ModulePatcher;
 import jdk.internal.perf.PerfCounter;
 
 /**
  * A {@code ModuleFinder} that finds modules that are linked into the
  * run-time image.
  *
  * The modules linked into the run-time image are assumed to have the
  * Packages attribute.
  */
 
-class SystemModuleFinder implements ModuleFinder {
+public class SystemModuleFinder implements ModuleFinder {
 
     private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
 
     private static final PerfCounter initTime
         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");

@@ -82,90 +81,30 @@
     private static final PerfCounter exportsCount
         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
     // ImageReader used to access all modules in the image
     private static final ImageReader imageReader;
 
-    // the set of modules in the run-time image
-    private static final Set<ModuleReference> modules;
+    // singleton finder to find modules in the run-time images
+    private static final SystemModuleFinder INSTANCE;
 
-    // maps module name to module reference
-    private static final Map<String, ModuleReference> nameToModule;
+    public static SystemModuleFinder getInstance() {
+        return INSTANCE;
+    }
 
     /**
      * For now, the module references are created eagerly on the assumption
      * that service binding will require all modules to be located.
      */
     static {
         long t0 = System.nanoTime();
         imageReader = ImageReaderFactory.getImageReader();
 
-        String[] names = moduleNames();
-        ModuleDescriptor[] descriptors = descriptors(names);
-
-        int n = names.length;
-        moduleCount.add(n);
-
-        ModuleReference[] mods = new ModuleReference[n];
-
-        @SuppressWarnings(value = {"rawtypes", "unchecked"})
-        Entry<String, ModuleReference>[] map
-            = (Entry<String, ModuleReference>[])new Entry[n];
-
-        for (int i = 0; i < n; i++) {
-            ModuleDescriptor md = descriptors[i];
-
-            // create the ModuleReference
-            ModuleReference mref = toModuleReference(md, hashSupplier(i, names[i]));
-
-            mods[i] = mref;
-            map[i] = Map.entry(names[i], mref);
-
-            // counters
-            packageCount.add(md.packages().size());
-            exportsCount.add(md.exports().size());
-        }
-
-        modules = Set.of(mods);
-        nameToModule = Map.ofEntries(map);
+        INSTANCE = new SystemModuleFinder();
 
         initTime.addElapsedTimeFrom(t0);
     }
 
-    /*
-     * Returns an array of ModuleDescriptor of the given module names.
-     *
-     * This obtains ModuleDescriptors from SystemModules class that is generated
-     * from the jlink system-modules plugin.  ModuleDescriptors have already
-     * been validated at link time.
-     *
-     * If java.base is patched, or fastpath is disabled for troubleshooting
-     * purpose, it will fall back to find system modules via jrt file system.
-     */
-    private static ModuleDescriptor[] descriptors(String[] names) {
-        // fastpath is enabled by default.
-        // It can be disabled for troubleshooting purpose.
-        boolean disabled =
-            System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
-
-        // fast loading of ModuleDescriptor of system modules
-        if (isFastPathSupported() && !disabled)
-            return SystemModules.modules();
-
-        // if fast loading of ModuleDescriptors is disabled
-        // fallback to read module-info.class
-        ModuleDescriptor[] descriptors = new ModuleDescriptor[names.length];
-        for (int i = 0; i < names.length; i++) {
-            String mn = names[i];
-            ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
-            descriptors[i] = ModuleDescriptor.read(imageReader.getResourceBuffer(loc));
-
-            // add the recorded hashes of tied modules
-            Hashes.add(descriptors[i]);
-        }
-        return descriptors;
-    }
-
     private static boolean isFastPathSupported() {
        return SystemModules.MODULE_NAMES.length > 0;
     }
 
     private static String[] moduleNames() {

@@ -176,60 +115,24 @@
         // this happens when java.base is patched with java.base
         // from an exploded image
         return imageReader.getModuleNames();
     }
 
-    private static ModuleReference toModuleReference(ModuleDescriptor md,
-                                                     HashSupplier hash)
-    {
-        String mn = md.name();
-        URI uri = JNUA.create("jrt", "/".concat(mn));
-
-        Supplier<ModuleReader> readerSupplier = new Supplier<>() {
-            @Override
-            public ModuleReader get() {
-                return new ImageModuleReader(mn, uri);
-            }
-        };
-
-        ModuleReference mref =
-            new ModuleReference(md, uri, readerSupplier, hash);
-
-        // may need a reference to a patched module if --patch-module specified
-        mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
-
-        return mref;
-    }
-
-    private static HashSupplier hashSupplier(int index, String name) {
-        if (isFastPathSupported()) {
-            return new HashSupplier() {
-                @Override
-                public byte[] generate(String algorithm) {
-                    return SystemModules.MODULES_TO_HASH[index];
-                }
-            };
-        } else {
-            return Hashes.hashFor(name);
-        }
-    }
 
-    /*
-     * This helper class is only used when SystemModules is patched.
-     * It will get the recorded hashes from module-info.class.
+    /**
+     * Helper class to use the recorded hashes to create a HashSupplier
      */
     private static class Hashes {
         static Map<String, byte[]> hashes = new HashMap<>();
 
-        static void add(ModuleDescriptor descriptor) {
-            Optional<ModuleHashes> ohashes = descriptor.hashes();
-            if (ohashes.isPresent()) {
-                hashes.putAll(ohashes.get().hashes());
+        static void add(ModuleHashes recordedHashes) {
+            if (recordedHashes != null) {
+                hashes.putAll(recordedHashes.hashes());
             }
         }
 
-        static HashSupplier hashFor(String name) {
+        static HashSupplier hashSupplierFor(String name) {
             if (!hashes.containsKey(name))
                 return null;
 
             return new HashSupplier() {
                 @Override

@@ -238,11 +141,82 @@
                 }
             };
         }
     }
 
-    SystemModuleFinder() { }
+    // the set of modules in the run-time image
+    private final Set<ModuleReference> modules;
+
+    // maps module name to module reference
+    private final Map<String, ModuleReference> nameToModule;
+
+    private SystemModuleFinder() {
+        String[] names = moduleNames();
+        int n = names.length;
+        moduleCount.add(n);
+
+        // fastpath is enabled by default.
+        // It can be disabled for troubleshooting purpose.
+        boolean disabled =
+            System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
+
+        ModuleDescriptor[] descriptors;
+        ModuleHashes[] recordedHashes;
+        ModuleResolution[] moduleResolutions;
+
+        // fast loading of ModuleDescriptor of system modules
+        if (isFastPathSupported() && !disabled) {
+            descriptors = SystemModules.descriptors();
+            recordedHashes = SystemModules.hashes();
+            moduleResolutions = SystemModules.moduleResolutions();
+        } else {
+            // if fast loading of ModuleDescriptors is disabled
+            // fallback to read module-info.class
+            descriptors = new ModuleDescriptor[n];
+            recordedHashes = new ModuleHashes[n];
+            moduleResolutions = new ModuleResolution[n];
+            for (int i = 0; i < names.length; i++) {
+                String mn = names[i];
+                ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
+                ModuleInfo.Attributes attrs =
+                    ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
+                descriptors[i] = attrs.descriptor();
+                recordedHashes[i] = attrs.recordedHashes();
+                moduleResolutions[i] = attrs.moduleResolution();
+            }
+        }
+
+        // record the hashes to build HashSupplier
+        for (ModuleHashes mh : recordedHashes) {
+            Hashes.add(mh);
+        }
+
+        ModuleReference[] mods = new ModuleReference[n];
+
+        @SuppressWarnings(value = {"rawtypes", "unchecked"})
+        Entry<String, ModuleReference>[] map
+            = (Entry<String, ModuleReference>[])new Entry[n];
+
+        for (int i = 0; i < n; i++) {
+            ModuleDescriptor md = descriptors[i];
+
+            // create the ModuleReference
+            ModuleReference mref = toModuleReference(md,
+                                                     recordedHashes[i],
+                                                     Hashes.hashSupplierFor(names[i]),
+                                                     moduleResolutions[i]);
+            mods[i] = mref;
+            map[i] = Map.entry(names[i], mref);
+
+            // counters
+            packageCount.add(md.packages().size());
+            exportsCount.add(md.exports().size());
+        }
+
+        modules = Set.of(mods);
+        nameToModule = Map.ofEntries(map);
+    }
 
     @Override
     public Optional<ModuleReference> find(String name) {
         Objects.requireNonNull(name);
         return Optional.ofNullable(nameToModule.get(name));

@@ -251,10 +225,34 @@
     @Override
     public Set<ModuleReference> findAll() {
         return modules;
     }
 
+    private ModuleReference toModuleReference(ModuleDescriptor md,
+                                              ModuleHashes recordedHashes,
+                                              HashSupplier hasher,
+                                              ModuleResolution mres) {
+        String mn = md.name();
+        URI uri = JNUA.create("jrt", "/".concat(mn));
+
+        Supplier<ModuleReader> readerSupplier = new Supplier<>() {
+            @Override
+            public ModuleReader get() {
+                return new ImageModuleReader(mn, uri);
+            }
+        };
+
+        ModuleReference mref =
+            new ModuleReferenceImpl(md, uri, readerSupplier, null,
+                                    recordedHashes, hasher, mres);
+
+        // may need a reference to a patched module if --patch-module specified
+        mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
+
+        return mref;
+    }
+
 
     /**
      * A ModuleReader for reading resources from a module linked into the
      * run-time image.
      */
< prev index next >