< prev index next >

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

Print this page




  63 /**
  64  * A {@code ModuleFinder} that finds modules that are linked into the
  65  * run-time image.
  66  *
  67  * The modules linked into the run-time image are assumed to have the
  68  * Packages attribute.
  69  */
  70 
  71 public class SystemModuleFinder implements ModuleFinder {
  72 
  73     private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
  74 
  75     private static final PerfCounter initTime
  76         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
  77     private static final PerfCounter moduleCount
  78         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.modules");
  79     private static final PerfCounter packageCount
  80         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
  81     private static final PerfCounter exportsCount
  82         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
  83     // ImageReader used to access all modules in the image
  84     private static final ImageReader imageReader;
  85 
  86     // singleton finder to find modules in the run-time images
  87     private static final SystemModuleFinder INSTANCE;
  88 
  89     public static SystemModuleFinder getInstance() {
  90         return INSTANCE;
  91     }
  92 
  93     /**
  94      * For now, the module references are created eagerly on the assumption
  95      * that service binding will require all modules to be located.
  96      */
  97     static {
  98         long t0 = System.nanoTime();
  99         imageReader = ImageReaderFactory.getImageReader();
 100 
 101         INSTANCE = new SystemModuleFinder();
 102 
 103         initTime.addElapsedTimeFrom(t0);
 104     }
 105 
















 106     private static boolean isFastPathSupported() {
 107        return SystemModules.MODULE_NAMES.length > 0;
 108     }
 109 
 110     private static String[] moduleNames() {
 111         if (isFastPathSupported())
 112             // module names recorded at link time
 113             return SystemModules.MODULE_NAMES;
 114 
 115         // this happens when java.base is patched with java.base
 116         // from an exploded image
 117         return imageReader.getModuleNames();
 118     }
 119 
 120     // the set of modules in the run-time image
 121     private final Set<ModuleReference> modules;
 122 
 123     // maps module name to module reference
 124     private final Map<String, ModuleReference> nameToModule;
 125 
 126     // module name to hashes
 127     private final Map<String, byte[]> hashes;
 128 
 129     private SystemModuleFinder() {
 130         String[] names = moduleNames();
 131         int n = names.length;
 132         moduleCount.add(n);
 133 
 134         // fastpath is enabled by default.
 135         // It can be disabled for troubleshooting purpose.
 136         boolean disabled =
 137             System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
 138 
 139         ModuleDescriptor[] descriptors;
 140         ModuleHashes[] recordedHashes;
 141         ModuleResolution[] moduleResolutions;
 142 
 143         // fast loading of ModuleDescriptor of system modules
 144         if (isFastPathSupported() && !disabled) {
 145             descriptors = SystemModules.descriptors();
 146             recordedHashes = SystemModules.hashes();
 147             moduleResolutions = SystemModules.moduleResolutions();
 148         } else {
 149             // if fast loading of ModuleDescriptors is disabled
 150             // fallback to read module-info.class
 151             descriptors = new ModuleDescriptor[n];
 152             recordedHashes = new ModuleHashes[n];
 153             moduleResolutions = new ModuleResolution[n];

 154             for (int i = 0; i < names.length; i++) {
 155                 String mn = names[i];
 156                 ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
 157                 ModuleInfo.Attributes attrs =
 158                     ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
 159                 descriptors[i] = attrs.descriptor();
 160                 recordedHashes[i] = attrs.recordedHashes();
 161                 moduleResolutions[i] = attrs.moduleResolution();
 162             }
 163         }
 164 
 165         Map<String, byte[]> hashes = null;
 166         boolean secondSeen = false;
 167         // record the hashes to build HashSupplier
 168         for (ModuleHashes mh : recordedHashes) {
 169             if (mh != null) {
 170                 // if only one module contain ModuleHashes, use it
 171                 if (hashes == null) {
 172                     hashes = mh.hashes();
 173                 } else {


 274                     sm.checkPermission(uc.getPermission());
 275                 } catch (IOException ioe) {
 276                     throw new UncheckedIOException(ioe);
 277                 }
 278             }
 279         }
 280 
 281         ImageModuleReader(String module, URI uri) {
 282             checkPermissionToConnect(uri);
 283             this.module = module;
 284         }
 285 
 286         /**
 287          * Returns the ImageLocation for the given resource, {@code null}
 288          * if not found.
 289          */
 290         private ImageLocation findImageLocation(String name) throws IOException {
 291             Objects.requireNonNull(name);
 292             if (closed)
 293                 throw new IOException("ModuleReader is closed");

 294             if (imageReader != null) {
 295                 return imageReader.findLocation(module, name);
 296             } else {
 297                 // not an images build
 298                 return null;
 299             }
 300         }
 301 
 302         @Override
 303         public Optional<URI> find(String name) throws IOException {
 304             ImageLocation location = findImageLocation(name);
 305             if (location != null) {
 306                 URI u = URI.create("jrt:/" + module + "/" + name);
 307                 return Optional.of(u);
 308             } else {
 309                 return Optional.empty();
 310             }
 311         }
 312 
 313         @Override
 314         public Optional<InputStream> open(String name) throws IOException {
 315             return read(name).map(this::toInputStream);
 316         }
 317 
 318         private InputStream toInputStream(ByteBuffer bb) { // ## -> ByteBuffer?
 319             try {
 320                 int rem = bb.remaining();
 321                 byte[] bytes = new byte[rem];
 322                 bb.get(bytes);
 323                 return new ByteArrayInputStream(bytes);
 324             } finally {
 325                 release(bb);
 326             }
 327         }
 328 
 329         @Override
 330         public Optional<ByteBuffer> read(String name) throws IOException {
 331             ImageLocation location = findImageLocation(name);
 332             if (location != null) {
 333                 return Optional.of(imageReader.getResourceBuffer(location));
 334             } else {
 335                 return Optional.empty();
 336             }
 337         }
 338 
 339         @Override
 340         public void release(ByteBuffer bb) {
 341             Objects.requireNonNull(bb);
 342             ImageReader.releaseByteBuffer(bb);
 343         }
 344 
 345         @Override
 346         public Stream<String> list() throws IOException {
 347             if (closed)
 348                 throw new IOException("ModuleReader is closed");
 349 
 350             Spliterator<String> s = new ModuleContentSpliterator(module);
 351             return StreamSupport.stream(s, false);
 352         }
 353 


 355         public void close() {
 356             // nothing else to do
 357             closed = true;
 358         }
 359     }
 360 
 361     /**
 362      * A Spliterator for traversing the resources of a module linked into the
 363      * run-time image.
 364      */
 365     static class ModuleContentSpliterator implements Spliterator<String> {
 366         final String moduleRoot;
 367         final Deque<ImageReader.Node> stack;
 368         Iterator<ImageReader.Node> iterator;
 369 
 370         ModuleContentSpliterator(String module) throws IOException {
 371             moduleRoot = "/modules/" + module;
 372             stack = new ArrayDeque<>();
 373 
 374             // push the root node to the stack to get started
 375             ImageReader.Node dir = imageReader.findNode(moduleRoot);
 376             if (dir == null || !dir.isDirectory())
 377                 throw new IOException(moduleRoot + " not a directory");
 378             stack.push(dir);
 379             iterator = Collections.emptyIterator();
 380         }
 381 
 382         /**
 383          * Returns the name of the next non-directory node or {@code null} if
 384          * there are no remaining nodes to visit.
 385          */
 386         private String next() throws IOException {
 387             for (;;) {
 388                 while (iterator.hasNext()) {
 389                     ImageReader.Node node = iterator.next();
 390                     String name = node.getName();
 391                     if (node.isDirectory()) {
 392                         // build node
 393                         ImageReader.Node dir = imageReader.findNode(name);
 394                         assert dir.isDirectory();
 395                         stack.push(dir);
 396                     } else {
 397                         // strip /modules/$MODULE/ prefix
 398                         return name.substring(moduleRoot.length() + 1);
 399                     }
 400                 }
 401 
 402                 if (stack.isEmpty()) {
 403                     return null;
 404                 } else {
 405                     ImageReader.Node dir = stack.poll();
 406                     assert dir.isDirectory();
 407                     iterator = dir.getChildren().iterator();
 408                 }
 409             }
 410         }
 411 
 412         @Override
 413         public boolean tryAdvance(Consumer<? super String> action) {




  63 /**
  64  * A {@code ModuleFinder} that finds modules that are linked into the
  65  * run-time image.
  66  *
  67  * The modules linked into the run-time image are assumed to have the
  68  * Packages attribute.
  69  */
  70 
  71 public class SystemModuleFinder implements ModuleFinder {
  72 
  73     private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
  74 
  75     private static final PerfCounter initTime
  76         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
  77     private static final PerfCounter moduleCount
  78         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.modules");
  79     private static final PerfCounter packageCount
  80         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
  81     private static final PerfCounter exportsCount
  82         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");


  83 
  84     // singleton finder to find modules in the run-time images
  85     private static final SystemModuleFinder INSTANCE;
  86 
  87     public static SystemModuleFinder getInstance() {
  88         return INSTANCE;
  89     }
  90 
  91     /**
  92      * For now, the module references are created eagerly on the assumption
  93      * that service binding will require all modules to be located.
  94      */
  95     static {
  96         long t0 = System.nanoTime();

  97 
  98         INSTANCE = new SystemModuleFinder();
  99 
 100         initTime.addElapsedTimeFrom(t0);
 101     }
 102 
 103     /**
 104      * Holder class for the ImageReader
 105      */
 106     private static class SystemImage {
 107         static final ImageReader READER;
 108         static {
 109             long t0 = System.nanoTime();
 110             READER = ImageReaderFactory.getImageReader();
 111             initTime.addElapsedTimeFrom(t0);
 112         }
 113 
 114         static ImageReader reader() {
 115             return READER;
 116         }
 117     }
 118 
 119     private static boolean isFastPathSupported() {
 120        return SystemModules.MODULE_NAMES.length > 0;
 121     }
 122 
 123     private static String[] moduleNames() {
 124         if (isFastPathSupported())
 125             // module names recorded at link time
 126             return SystemModules.MODULE_NAMES;
 127 
 128         // this happens when java.base is patched with java.base
 129         // from an exploded image
 130         return SystemImage.reader().getModuleNames();
 131     }
 132 
 133     // the set of modules in the run-time image
 134     private final Set<ModuleReference> modules;
 135 
 136     // maps module name to module reference
 137     private final Map<String, ModuleReference> nameToModule;
 138 
 139     // module name to hashes
 140     private final Map<String, byte[]> hashes;
 141 
 142     private SystemModuleFinder() {
 143         String[] names = moduleNames();
 144         int n = names.length;
 145         moduleCount.add(n);
 146 
 147         // fastpath is enabled by default.
 148         // It can be disabled for troubleshooting purpose.
 149         boolean disabled =
 150             System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
 151 
 152         ModuleDescriptor[] descriptors;
 153         ModuleHashes[] recordedHashes;
 154         ModuleResolution[] moduleResolutions;
 155 
 156         // fast loading of ModuleDescriptor of system modules
 157         if (isFastPathSupported() && !disabled) {
 158             descriptors = SystemModules.descriptors();
 159             recordedHashes = SystemModules.hashes();
 160             moduleResolutions = SystemModules.moduleResolutions();
 161         } else {
 162             // if fast loading of ModuleDescriptors is disabled
 163             // fallback to read module-info.class
 164             descriptors = new ModuleDescriptor[n];
 165             recordedHashes = new ModuleHashes[n];
 166             moduleResolutions = new ModuleResolution[n];
 167             ImageReader imageReader = SystemImage.reader();
 168             for (int i = 0; i < names.length; i++) {
 169                 String mn = names[i];
 170                 ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
 171                 ModuleInfo.Attributes attrs =
 172                     ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
 173                 descriptors[i] = attrs.descriptor();
 174                 recordedHashes[i] = attrs.recordedHashes();
 175                 moduleResolutions[i] = attrs.moduleResolution();
 176             }
 177         }
 178 
 179         Map<String, byte[]> hashes = null;
 180         boolean secondSeen = false;
 181         // record the hashes to build HashSupplier
 182         for (ModuleHashes mh : recordedHashes) {
 183             if (mh != null) {
 184                 // if only one module contain ModuleHashes, use it
 185                 if (hashes == null) {
 186                     hashes = mh.hashes();
 187                 } else {


 288                     sm.checkPermission(uc.getPermission());
 289                 } catch (IOException ioe) {
 290                     throw new UncheckedIOException(ioe);
 291                 }
 292             }
 293         }
 294 
 295         ImageModuleReader(String module, URI uri) {
 296             checkPermissionToConnect(uri);
 297             this.module = module;
 298         }
 299 
 300         /**
 301          * Returns the ImageLocation for the given resource, {@code null}
 302          * if not found.
 303          */
 304         private ImageLocation findImageLocation(String name) throws IOException {
 305             Objects.requireNonNull(name);
 306             if (closed)
 307                 throw new IOException("ModuleReader is closed");
 308             ImageReader imageReader = SystemImage.reader();
 309             if (imageReader != null) {
 310                 return imageReader.findLocation(module, name);
 311             } else {
 312                 // not an images build
 313                 return null;
 314             }
 315         }
 316 
 317         @Override
 318         public Optional<URI> find(String name) throws IOException {
 319             ImageLocation location = findImageLocation(name);
 320             if (location != null) {
 321                 URI u = URI.create("jrt:/" + module + "/" + name);
 322                 return Optional.of(u);
 323             } else {
 324                 return Optional.empty();
 325             }
 326         }
 327 
 328         @Override
 329         public Optional<InputStream> open(String name) throws IOException {
 330             return read(name).map(this::toInputStream);
 331         }
 332 
 333         private InputStream toInputStream(ByteBuffer bb) { // ## -> ByteBuffer?
 334             try {
 335                 int rem = bb.remaining();
 336                 byte[] bytes = new byte[rem];
 337                 bb.get(bytes);
 338                 return new ByteArrayInputStream(bytes);
 339             } finally {
 340                 release(bb);
 341             }
 342         }
 343 
 344         @Override
 345         public Optional<ByteBuffer> read(String name) throws IOException {
 346             ImageLocation location = findImageLocation(name);
 347             if (location != null) {
 348                 return Optional.of(SystemImage.reader().getResourceBuffer(location));
 349             } else {
 350                 return Optional.empty();
 351             }
 352         }
 353 
 354         @Override
 355         public void release(ByteBuffer bb) {
 356             Objects.requireNonNull(bb);
 357             ImageReader.releaseByteBuffer(bb);
 358         }
 359 
 360         @Override
 361         public Stream<String> list() throws IOException {
 362             if (closed)
 363                 throw new IOException("ModuleReader is closed");
 364 
 365             Spliterator<String> s = new ModuleContentSpliterator(module);
 366             return StreamSupport.stream(s, false);
 367         }
 368 


 370         public void close() {
 371             // nothing else to do
 372             closed = true;
 373         }
 374     }
 375 
 376     /**
 377      * A Spliterator for traversing the resources of a module linked into the
 378      * run-time image.
 379      */
 380     static class ModuleContentSpliterator implements Spliterator<String> {
 381         final String moduleRoot;
 382         final Deque<ImageReader.Node> stack;
 383         Iterator<ImageReader.Node> iterator;
 384 
 385         ModuleContentSpliterator(String module) throws IOException {
 386             moduleRoot = "/modules/" + module;
 387             stack = new ArrayDeque<>();
 388 
 389             // push the root node to the stack to get started
 390             ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
 391             if (dir == null || !dir.isDirectory())
 392                 throw new IOException(moduleRoot + " not a directory");
 393             stack.push(dir);
 394             iterator = Collections.emptyIterator();
 395         }
 396 
 397         /**
 398          * Returns the name of the next non-directory node or {@code null} if
 399          * there are no remaining nodes to visit.
 400          */
 401         private String next() throws IOException {
 402             for (;;) {
 403                 while (iterator.hasNext()) {
 404                     ImageReader.Node node = iterator.next();
 405                     String name = node.getName();
 406                     if (node.isDirectory()) {
 407                         // build node
 408                         ImageReader.Node dir = SystemImage.reader().findNode(name);
 409                         assert dir.isDirectory();
 410                         stack.push(dir);
 411                     } else {
 412                         // strip /modules/$MODULE/ prefix
 413                         return name.substring(moduleRoot.length() + 1);
 414                     }
 415                 }
 416 
 417                 if (stack.isEmpty()) {
 418                     return null;
 419                 } else {
 420                     ImageReader.Node dir = stack.poll();
 421                     assert dir.isDirectory();
 422                     iterator = dir.getChildren().iterator();
 423                 }
 424             }
 425         }
 426 
 427         @Override
 428         public boolean tryAdvance(Consumer<? super String> action) {


< prev index next >