1 /* 2 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang.reflect; 27 28 import java.lang.module.Configuration; 29 import java.lang.module.ModuleDescriptor; 30 import java.lang.module.ResolvedModule; 31 import java.util.ArrayDeque; 32 import java.util.ArrayList; 33 import java.util.Collections; 34 import java.util.Deque; 35 import java.util.HashMap; 36 import java.util.HashSet; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.Objects; 40 import java.util.Optional; 41 import java.util.Set; 42 import java.util.concurrent.CopyOnWriteArrayList; 43 import java.util.function.Function; 44 import java.util.stream.Collectors; 45 import java.util.stream.Stream; 46 47 import jdk.internal.loader.ClassLoaderValue; 48 import jdk.internal.loader.Loader; 49 import jdk.internal.loader.LoaderPool; 50 import jdk.internal.misc.SharedSecrets; 51 import jdk.internal.module.Modules; 52 import jdk.internal.module.ServicesCatalog; 53 import sun.security.util.SecurityConstants; 54 55 56 /** 57 * A layer of modules in the Java virtual machine. 58 * 59 * <p> A layer is created from a graph of modules in a {@link Configuration} 60 * and a function that maps each module to a {@link ClassLoader}. 61 * Creating a layer informs the Java virtual machine about the classes that 62 * may be loaded from the modules so that the Java virtual machine knows which 63 * module that each class is a member of. </p> 64 * 65 * <p> Creating a layer creates a {@link Module} object for each {@link 66 * ResolvedModule} in the configuration. For each resolved module that is 67 * {@link ResolvedModule#reads() read}, the {@code Module} {@link 68 * Module#canRead reads} the corresponding run-time {@code Module}, which may 69 * be in the same layer or a {@link #parents() parent} layer. </p> 70 * 71 * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and 72 * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods 73 * provide convenient ways to create a {@code Layer} where all modules are 74 * mapped to a single class loader or where each module is mapped to its own 75 * class loader. The {@link #defineModules defineModules} method is for more 76 * advanced cases where modules are mapped to custom class loaders by means of 77 * a function specified to the method. Each of these methods has an instance 78 * and static variant. The instance methods create a layer with the receiver 79 * as the parent layer. The static methods are for more advanced cases where 80 * there can be more than one parent layer or where a {@link Layer.Controller 81 * Controller} is needed to control modules in the layer. </p> 82 * 83 * <p> A Java virtual machine has at least one non-empty layer, the {@link 84 * #boot() boot} layer, that is created when the Java virtual machine is 85 * started. The boot layer contains module {@code java.base} and is the only 86 * layer in the Java virtual machine with a module named "{@code java.base}". 87 * The modules in the boot layer are mapped to the bootstrap class loader and 88 * other class loaders that are <a href="../ClassLoader.html#builtinLoaders"> 89 * built-in</a> into the Java virtual machine. The boot layer will often be 90 * the {@link #parents() parent} when creating additional layers. </p> 91 * 92 * <p> Each {@code Module} in a layer is created so that it {@link 93 * Module#isExported(String) exports} and {@link Module#isOpen(String) opens} 94 * the packages described by its {@link ModuleDescriptor}. Qualified exports 95 * (where a package is exported to a set of target modules rather than all 96 * modules) are reified when creating the layer as follows: </p> 97 * <ul> 98 * <li> If module {@code X} exports a package to {@code Y}, and if the 99 * runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then 100 * the package is exported to {@code Module} {@code Y} (which may be in 101 * the same layer as {@code X} or a parent layer). </li> 102 * 103 * <li> If module {@code X} exports a package to {@code Y}, and if the 104 * runtime {@code Module} {@code X} does not read {@code Y} then target 105 * {@code Y} is located as if by invoking {@link #findModule(String) 106 * findModule} to find the module in the layer or its parent layers. If 107 * {@code Y} is found then the package is exported to the instance of 108 * {@code Y} that was found. If {@code Y} is not found then the qualified 109 * export is ignored. </li> 110 * </ul> 111 * 112 * <p> Qualified opens are handled in same way as qualified exports. </p> 113 * 114 * <p> As when creating a {@code Configuration}, 115 * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special 116 * treatment when creating a layer. An automatic module is created in the 117 * Java virtual machine as a {@code Module} that reads every unnamed {@code 118 * Module} in the Java virtual machine. </p> 119 * 120 * <p> Unless otherwise specified, passing a {@code null} argument to a method 121 * in this class causes a {@link NullPointerException NullPointerException} to 122 * be thrown. </p> 123 * 124 * <h3> Example usage: </h3> 125 * 126 * <p> This example creates a configuration by resolving a module named 127 * "{@code myapp}" with the configuration for the boot layer as the parent. It 128 * then creates a new layer with the modules in this configuration. All modules 129 * are defined to the same class loader. </p> 130 * 131 * <pre>{@code 132 * ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3); 133 * 134 * Layer parent = Layer.boot(); 135 * 136 * Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp")); 137 * 138 * ClassLoader scl = ClassLoader.getSystemClassLoader(); 139 * 140 * Layer layer = parent.defineModulesWithOneLoader(cf, scl); 141 * 142 * Class<?> c = layer.findLoader("myapp").loadClass("app.Main"); 143 * }</pre> 144 * 145 * @since 9 146 * @spec JPMS 147 * @see Module#getLayer() 148 */ 149 150 public final class Layer { 151 152 // the empty Layer 153 private static final Layer EMPTY_LAYER 154 = new Layer(Configuration.empty(), List.of(), null); 155 156 // the configuration from which this Layer was created 157 private final Configuration cf; 158 159 // parent layers, empty in the case of the empty layer 160 private final List<Layer> parents; 161 162 // maps module name to jlr.Module 163 private final Map<String, Module> nameToModule; 164 165 /** 166 * Creates a new Layer from the modules in the given configuration. 167 */ 168 private Layer(Configuration cf, 169 List<Layer> parents, 170 Function<String, ClassLoader> clf) 171 { 172 this.cf = cf; 173 this.parents = parents; // no need to do defensive copy 174 175 Map<String, Module> map; 176 if (parents.isEmpty()) { 177 map = Collections.emptyMap(); 178 } else { 179 map = Module.defineModules(cf, clf, this); 180 } 181 this.nameToModule = map; // no need to do defensive copy 182 } 183 184 /** 185 * Controls a layer. The static methods defined by {@link Layer} to create 186 * module layers return a {@code Controller} that can be used to control 187 * modules in the layer. 188 * 189 * <p> Unless otherwise specified, passing a {@code null} argument to a 190 * method in this class causes a {@link NullPointerException 191 * NullPointerException} to be thrown. </p> 192 * 193 * @apiNote Care should be taken with {@code Controller} objects, they 194 * should never be shared with untrusted code. 195 * 196 * @since 9 197 * @spec JPMS 198 */ 199 public static final class Controller { 200 private final Layer layer; 201 202 Controller(Layer layer) { 203 this.layer = layer; 204 } 205 206 /** 207 * Returns the layer that this object controls. 208 * 209 * @return the layer 210 */ 211 public Layer layer() { 212 return layer; 213 } 214 215 private void ensureInLayer(Module source) { 216 if (source.getLayer() != layer) 217 throw new IllegalArgumentException(source + " not in layer"); 218 } 219 220 221 /** 222 * Updates module {@code source} in the layer to read module 223 * {@code target}. This method is a no-op if {@code source} already 224 * reads {@code target}. 225 * 226 * @implNote <em>Read edges</em> added by this method are <em>weak</em> 227 * and do not prevent {@code target} from being GC'ed when {@code source} 228 * is strongly reachable. 229 * 230 * @param source 231 * The source module 232 * @param target 233 * The target module to read 234 * 235 * @return This controller 236 * 237 * @throws IllegalArgumentException 238 * If {@code source} is not in the layer 239 * 240 * @see Module#addReads 241 */ 242 public Controller addReads(Module source, Module target) { 243 ensureInLayer(source); 244 Objects.requireNonNull(target); 245 Modules.addReads(source, target); 246 return this; 247 } 248 249 /** 250 * Updates module {@code source} in the layer to open a package to 251 * module {@code target}. This method is a no-op if {@code source} 252 * already opens the package to at least {@code target}. 253 * 254 * @param source 255 * The source module 256 * @param pn 257 * The package name 258 * @param target 259 * The target module to read 260 * 261 * @return This controller 262 * 263 * @throws IllegalArgumentException 264 * If {@code source} is not in the layer or the package is not 265 * in the source module 266 * 267 * @see Module#addOpens 268 */ 269 public Controller addOpens(Module source, String pn, Module target) { 270 ensureInLayer(source); 271 Objects.requireNonNull(pn); 272 Objects.requireNonNull(target); 273 Modules.addOpens(source, pn, target); 274 return this; 275 } 276 } 277 278 279 /** 280 * Creates a new layer, with this layer as its parent, by defining the 281 * modules in the given {@code Configuration} to the Java virtual machine. 282 * This method creates one class loader and defines all modules to that 283 * class loader. The {@link ClassLoader#getParent() parent} of each class 284 * loader is the given parent class loader. This method works exactly as 285 * specified by the static {@link 286 * #defineModulesWithOneLoader(Configuration,List,ClassLoader) 287 * defineModulesWithOneLoader} method when invoked with this layer as the 288 * parent. In other words, if this layer is {@code thisLayer} then this 289 * method is equivalent to invoking: 290 * <pre> {@code 291 * Layer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer(); 292 * }</pre> 293 * 294 * @param cf 295 * The configuration for the layer 296 * @param parentLoader 297 * The parent class loader for the class loader created by this 298 * method; may be {@code null} for the bootstrap class loader 299 * 300 * @return The newly created layer 301 * 302 * @throws IllegalArgumentException 303 * If the parent of the given configuration is not the configuration 304 * for this layer 305 * @throws LayerInstantiationException 306 * If the layer cannot be created for any of the reasons specified 307 * by the static {@code defineModulesWithOneLoader} method 308 * @throws SecurityException 309 * If {@code RuntimePermission("createClassLoader")} or 310 * {@code RuntimePermission("getClassLoader")} is denied by 311 * the security manager 312 * 313 * @see #findLoader 314 */ 315 public Layer defineModulesWithOneLoader(Configuration cf, 316 ClassLoader parentLoader) { 317 return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer(); 318 } 319 320 321 /** 322 * Creates a new layer, with this layer as its parent, by defining the 323 * modules in the given {@code Configuration} to the Java virtual machine. 324 * Each module is defined to its own {@link ClassLoader} created by this 325 * method. The {@link ClassLoader#getParent() parent} of each class loader 326 * is the given parent class loader. This method works exactly as specified 327 * by the static {@link 328 * #defineModulesWithManyLoaders(Configuration,List,ClassLoader) 329 * defineModulesWithManyLoaders} method when invoked with this layer as the 330 * parent. In other words, if this layer is {@code thisLayer} then this 331 * method is equivalent to invoking: 332 * <pre> {@code 333 * Layer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer(); 334 * }</pre> 335 * 336 * @param cf 337 * The configuration for the layer 338 * @param parentLoader 339 * The parent class loader for each of the class loaders created by 340 * this method; may be {@code null} for the bootstrap class loader 341 * 342 * @return The newly created layer 343 * 344 * @throws IllegalArgumentException 345 * If the parent of the given configuration is not the configuration 346 * for this layer 347 * @throws LayerInstantiationException 348 * If the layer cannot be created for any of the reasons specified 349 * by the static {@code defineModulesWithManyLoaders} method 350 * @throws SecurityException 351 * If {@code RuntimePermission("createClassLoader")} or 352 * {@code RuntimePermission("getClassLoader")} is denied by 353 * the security manager 354 * 355 * @see #findLoader 356 */ 357 public Layer defineModulesWithManyLoaders(Configuration cf, 358 ClassLoader parentLoader) { 359 return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer(); 360 } 361 362 363 /** 364 * Creates a new layer, with this layer as its parent, by defining the 365 * modules in the given {@code Configuration} to the Java virtual machine. 366 * Each module is mapped, by name, to its class loader by means of the 367 * given function. This method works exactly as specified by the static 368 * {@link #defineModules(Configuration,List,Function) defineModules} 369 * method when invoked with this layer as the parent. In other words, if 370 * this layer is {@code thisLayer} then this method is equivalent to 371 * invoking: 372 * <pre> {@code 373 * Layer.defineModules(cf, List.of(thisLayer), clf).layer(); 374 * }</pre> 375 * 376 * @param cf 377 * The configuration for the layer 378 * @param clf 379 * The function to map a module name to a class loader 380 * 381 * @return The newly created layer 382 * 383 * @throws IllegalArgumentException 384 * If the parent of the given configuration is not the configuration 385 * for this layer 386 * @throws LayerInstantiationException 387 * If the layer cannot be created for any of the reasons specified 388 * by the static {@code defineModules} method 389 * @throws SecurityException 390 * If {@code RuntimePermission("getClassLoader")} is denied by 391 * the security manager 392 */ 393 public Layer defineModules(Configuration cf, 394 Function<String, ClassLoader> clf) { 395 return defineModules(cf, List.of(this), clf).layer(); 396 } 397 398 /** 399 * Creates a new layer by defining the modules in the given {@code 400 * Configuration} to the Java virtual machine. This method creates one 401 * class loader and defines all modules to that class loader. 402 * 403 * <p> The class loader created by this method implements <em>direct 404 * delegation</em> when loading types from modules. When its {@link 405 * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to 406 * load a class then it uses the package name of the class to map it to a 407 * module. This may be a module in this layer and hence defined to the same 408 * class loader. It may be a package in a module in a parent layer that is 409 * exported to one or more of the modules in this layer. The class 410 * loader delegates to the class loader of the module, throwing {@code 411 * ClassNotFoundException} if not found by that class loader. 412 * When {@code loadClass} is invoked to load classes that do not map to a 413 * module then it delegates to the parent class loader. </p> 414 * 415 * <p> Attempting to create a layer with all modules defined to the same 416 * class loader can fail for the following reasons: 417 * 418 * <ul> 419 * 420 * <li><p> <em>Overlapping packages</em>: Two or more modules in the 421 * configuration have the same package. </p></li> 422 * 423 * <li><p> <em>Split delegation</em>: The resulting class loader would 424 * need to delegate to more than one class loader in order to load types 425 * in a specific package. </p></li> 426 * 427 * </ul> 428 * 429 * <p> In addition, a layer cannot be created if the configuration contains 430 * a module named "{@code java.base}", or a module contains a package named 431 * "{@code java}" or a package with a name starting with "{@code java.}". </p> 432 * 433 * <p> If there is a security manager then the class loader created by 434 * this method will load classes and resources with privileges that are 435 * restricted by the calling context of this method. </p> 436 * 437 * @param cf 438 * The configuration for the layer 439 * @param parentLayers 440 * The list of parent layers in search order 441 * @param parentLoader 442 * The parent class loader for the class loader created by this 443 * method; may be {@code null} for the bootstrap class loader 444 * 445 * @return A controller that controls the newly created layer 446 * 447 * @throws IllegalArgumentException 448 * If the parent configurations do not match the configuration of 449 * the parent layers, including order 450 * @throws LayerInstantiationException 451 * If all modules cannot be defined to the same class loader for any 452 * of the reasons listed above 453 * @throws SecurityException 454 * If {@code RuntimePermission("createClassLoader")} or 455 * {@code RuntimePermission("getClassLoader")} is denied by 456 * the security manager 457 * 458 * @see #findLoader 459 */ 460 public static Controller defineModulesWithOneLoader(Configuration cf, 461 List<Layer> parentLayers, 462 ClassLoader parentLoader) 463 { 464 List<Layer> parents = new ArrayList<>(parentLayers); 465 checkConfiguration(cf, parents); 466 467 checkCreateClassLoaderPermission(); 468 checkGetClassLoaderPermission(); 469 470 try { 471 Loader loader = new Loader(cf.modules(), parentLoader); 472 loader.initRemotePackageMap(cf, parents); 473 Layer layer = new Layer(cf, parents, mn -> loader); 474 return new Controller(layer); 475 } catch (IllegalArgumentException | IllegalStateException e) { 476 throw new LayerInstantiationException(e.getMessage()); 477 } 478 } 479 480 /** 481 * Creates a new layer by defining the modules in the given {@code 482 * Configuration} to the Java virtual machine. Each module is defined to 483 * its own {@link ClassLoader} created by this method. The {@link 484 * ClassLoader#getParent() parent} of each class loader is the given parent 485 * class loader. 486 * 487 * <p> The class loaders created by this method implement <em>direct 488 * delegation</em> when loading types from modules. When {@link 489 * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to 490 * load a class then it uses the package name of the class to map it to a 491 * module. The package may be in the module defined to the class loader. 492 * The package may be exported by another module in this layer to the 493 * module defined to the class loader. It may be in a package exported by a 494 * module in a parent layer. The class loader delegates to the class loader 495 * of the module, throwing {@code ClassNotFoundException} if not found by 496 * that class loader. 497 * When {@code loadClass} is invoked to load classes that do not map to a 498 * module then it delegates to the parent class loader. </p> 499 * 500 * <p> If there is a security manager then the class loaders created by 501 * this method will load classes and resources with privileges that are 502 * restricted by the calling context of this method. </p> 503 * 504 * @param cf 505 * The configuration for the layer 506 * @param parentLayers 507 * The list of parent layers in search order 508 * @param parentLoader 509 * The parent class loader for each of the class loaders created by 510 * this method; may be {@code null} for the bootstrap class loader 511 * 512 * @return A controller that controls the newly created layer 513 * 514 * @throws IllegalArgumentException 515 * If the parent configurations do not match the configuration of 516 * the parent layers, including order 517 * @throws LayerInstantiationException 518 * If the layer cannot be created because the configuration contains 519 * a module named "{@code java.base}" or a module contains a package 520 * named "{@code java}" or a package with a name starting with 521 * "{@code java.}" 522 * 523 * @throws SecurityException 524 * If {@code RuntimePermission("createClassLoader")} or 525 * {@code RuntimePermission("getClassLoader")} is denied by 526 * the security manager 527 * 528 * @see #findLoader 529 */ 530 public static Controller defineModulesWithManyLoaders(Configuration cf, 531 List<Layer> parentLayers, 532 ClassLoader parentLoader) 533 { 534 List<Layer> parents = new ArrayList<>(parentLayers); 535 checkConfiguration(cf, parents); 536 537 checkCreateClassLoaderPermission(); 538 checkGetClassLoaderPermission(); 539 540 LoaderPool pool = new LoaderPool(cf, parents, parentLoader); 541 try { 542 Layer layer = new Layer(cf, parents, pool::loaderFor); 543 return new Controller(layer); 544 } catch (IllegalArgumentException | IllegalStateException e) { 545 throw new LayerInstantiationException(e.getMessage()); 546 } 547 } 548 549 /** 550 * Creates a new layer by defining the modules in the given {@code 551 * Configuration} to the Java virtual machine. The given function maps each 552 * module in the configuration, by name, to a class loader. Creating the 553 * layer informs the Java virtual machine about the classes that may be 554 * loaded so that the Java virtual machine knows which module that each 555 * class is a member of. 556 * 557 * <p> The class loader delegation implemented by the class loaders must 558 * respect module readability. The class loaders should be 559 * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to 560 * avoid deadlocks during class loading. In addition, the entity creating 561 * a new layer with this method should arrange that the class loaders be 562 * ready to load from these modules before there are any attempts to load 563 * classes or resources. </p> 564 * 565 * <p> Creating a {@code Layer} can fail for the following reasons: </p> 566 * 567 * <ul> 568 * 569 * <li><p> Two or more modules with the same package are mapped to the 570 * same class loader. </p></li> 571 * 572 * <li><p> A module is mapped to a class loader that already has a 573 * module of the same name defined to it. </p></li> 574 * 575 * <li><p> A module is mapped to a class loader that has already 576 * defined types in any of the packages in the module. </p></li> 577 * 578 * </ul> 579 * 580 * <p> In addition, a layer cannot be created if the configuration contains 581 * a module named "{@code java.base}", a configuration contains a module 582 * with a package named "{@code java}" or a package name starting with 583 * "{@code java.}" and the module is mapped to a class loader other than 584 * the {@link ClassLoader#getPlatformClassLoader() platform class loader}, 585 * or the function to map a module name to a class loader returns 586 * {@code null}. </p> 587 * 588 * <p> If the function to map a module name to class loader throws an error 589 * or runtime exception then it is propagated to the caller of this method. 590 * </p> 591 * 592 * @apiNote It is implementation specific as to whether creating a Layer 593 * with this method is an atomic operation or not. Consequentially it is 594 * possible for this method to fail with some modules, but not all, defined 595 * to the Java virtual machine. 596 * 597 * @param cf 598 * The configuration for the layer 599 * @param parentLayers 600 * The list of parent layers in search order 601 * @param clf 602 * The function to map a module name to a class loader 603 * 604 * @return A controller that controls the newly created layer 605 * 606 * @throws IllegalArgumentException 607 * If the parent configurations do not match the configuration of 608 * the parent layers, including order 609 * @throws LayerInstantiationException 610 * If creating the layer fails for any of the reasons listed above 611 * @throws SecurityException 612 * If {@code RuntimePermission("getClassLoader")} is denied by 613 * the security manager 614 */ 615 public static Controller defineModules(Configuration cf, 616 List<Layer> parentLayers, 617 Function<String, ClassLoader> clf) 618 { 619 List<Layer> parents = new ArrayList<>(parentLayers); 620 checkConfiguration(cf, parents); 621 Objects.requireNonNull(clf); 622 623 checkGetClassLoaderPermission(); 624 625 // The boot layer is checked during module system initialization 626 if (boot() != null) { 627 checkForDuplicatePkgs(cf, clf); 628 } 629 630 try { 631 Layer layer = new Layer(cf, parents, clf); 632 return new Controller(layer); 633 } catch (IllegalArgumentException | IllegalStateException e) { 634 throw new LayerInstantiationException(e.getMessage()); 635 } 636 } 637 638 639 /** 640 * Checks that the parent configurations match the configuration of 641 * the parent layers. 642 */ 643 private static void checkConfiguration(Configuration cf, 644 List<Layer> parentLayers) 645 { 646 Objects.requireNonNull(cf); 647 648 List<Configuration> parentConfigurations = cf.parents(); 649 if (parentLayers.size() != parentConfigurations.size()) 650 throw new IllegalArgumentException("wrong number of parents"); 651 652 int index = 0; 653 for (Layer parent : parentLayers) { 654 if (parent.configuration() != parentConfigurations.get(index)) { 655 throw new IllegalArgumentException( 656 "Parent of configuration != configuration of this Layer"); 657 } 658 index++; 659 } 660 } 661 662 private static void checkCreateClassLoaderPermission() { 663 SecurityManager sm = System.getSecurityManager(); 664 if (sm != null) 665 sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); 666 } 667 668 private static void checkGetClassLoaderPermission() { 669 SecurityManager sm = System.getSecurityManager(); 670 if (sm != null) 671 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 672 } 673 674 /** 675 * Checks a configuration and the module-to-loader mapping to ensure that 676 * no two modules mapped to the same class loader have the same package. 677 * It also checks that no two automatic modules have the same package. 678 * 679 * @throws LayerInstantiationException 680 */ 681 private static void checkForDuplicatePkgs(Configuration cf, 682 Function<String, ClassLoader> clf) 683 { 684 // HashMap allows null keys 685 Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>(); 686 for (ResolvedModule resolvedModule : cf.modules()) { 687 ModuleDescriptor descriptor = resolvedModule.reference().descriptor(); 688 ClassLoader loader = clf.apply(descriptor.name()); 689 690 Set<String> loaderPackages 691 = loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>()); 692 693 for (String pkg : descriptor.packages()) { 694 boolean added = loaderPackages.add(pkg); 695 if (!added) { 696 throw fail("More than one module with package %s mapped" + 697 " to the same class loader", pkg); 698 } 699 } 700 } 701 } 702 703 /** 704 * Creates a LayerInstantiationException with the a message formatted from 705 * the given format string and arguments. 706 */ 707 private static LayerInstantiationException fail(String fmt, Object ... args) { 708 String msg = String.format(fmt, args); 709 return new LayerInstantiationException(msg); 710 } 711 712 713 /** 714 * Returns the configuration for this layer. 715 * 716 * @return The configuration for this layer 717 */ 718 public Configuration configuration() { 719 return cf; 720 } 721 722 723 /** 724 * Returns the list of this layer's parents unless this is the 725 * {@linkplain #empty empty layer}, which has no parents and so an 726 * empty list is returned. 727 * 728 * @return The list of this layer's parents 729 */ 730 public List<Layer> parents() { 731 return parents; 732 } 733 734 735 /** 736 * Returns an ordered stream of layers. The first element is is this layer, 737 * the remaining elements are the parent layers in DFS order. 738 * 739 * @implNote For now, the assumption is that the number of elements will 740 * be very low and so this method does not use a specialized spliterator. 741 */ 742 Stream<Layer> layers() { 743 List<Layer> allLayers = this.allLayers; 744 if (allLayers != null) 745 return allLayers.stream(); 746 747 allLayers = new ArrayList<>(); 748 Set<Layer> visited = new HashSet<>(); 749 Deque<Layer> stack = new ArrayDeque<>(); 750 visited.add(this); 751 stack.push(this); 752 753 while (!stack.isEmpty()) { 754 Layer layer = stack.pop(); 755 allLayers.add(layer); 756 757 // push in reverse order 758 for (int i = layer.parents.size() - 1; i >= 0; i--) { 759 Layer parent = layer.parents.get(i); 760 if (!visited.contains(parent)) { 761 visited.add(parent); 762 stack.push(parent); 763 } 764 } 765 } 766 767 this.allLayers = allLayers = Collections.unmodifiableList(allLayers); 768 return allLayers.stream(); 769 } 770 771 private volatile List<Layer> allLayers; 772 773 /** 774 * Returns the set of the modules in this layer. 775 * 776 * @return A possibly-empty unmodifiable set of the modules in this layer 777 */ 778 public Set<Module> modules() { 779 Set<Module> modules = this.modules; 780 if (modules == null) { 781 this.modules = modules = 782 Collections.unmodifiableSet(new HashSet<>(nameToModule.values())); 783 } 784 return modules; 785 } 786 787 private volatile Set<Module> modules; 788 789 790 /** 791 * Returns the module with the given name in this layer, or if not in this 792 * layer, the {@linkplain #parents parent} layers. Finding a module in 793 * parent layers is equivalent to invoking {@code findModule} on each 794 * parent, in search order, until the module is found or all parents have 795 * been searched. In a <em>tree of layers</em> then this is equivalent to 796 * a depth-first search. 797 * 798 * @param name 799 * The name of the module to find 800 * 801 * @return The module with the given name or an empty {@code Optional} 802 * if there isn't a module with this name in this layer or any 803 * parent layer 804 */ 805 public Optional<Module> findModule(String name) { 806 Objects.requireNonNull(name); 807 if (this == EMPTY_LAYER) 808 return Optional.empty(); 809 Module m = nameToModule.get(name); 810 if (m != null) 811 return Optional.of(m); 812 813 return layers() 814 .skip(1) // skip this layer 815 .map(l -> l.nameToModule) 816 .filter(map -> map.containsKey(name)) 817 .map(map -> map.get(name)) 818 .findAny(); 819 } 820 821 822 /** 823 * Returns the {@code ClassLoader} for the module with the given name. If 824 * a module of the given name is not in this layer then the {@link #parents 825 * parent} layers are searched in the manner specified by {@link 826 * #findModule(String) findModule}. 827 * 828 * <p> If there is a security manager then its {@code checkPermission} 829 * method is called with a {@code RuntimePermission("getClassLoader")} 830 * permission to check that the caller is allowed to get access to the 831 * class loader. </p> 832 * 833 * @apiNote This method does not return an {@code Optional<ClassLoader>} 834 * because `null` must be used to represent the bootstrap class loader. 835 * 836 * @param name 837 * The name of the module to find 838 * 839 * @return The ClassLoader that the module is defined to 840 * 841 * @throws IllegalArgumentException if a module of the given name is not 842 * defined in this layer or any parent of this layer 843 * 844 * @throws SecurityException if denied by the security manager 845 */ 846 public ClassLoader findLoader(String name) { 847 Optional<Module> om = findModule(name); 848 849 // can't use map(Module::getClassLoader) as class loader can be null 850 if (om.isPresent()) { 851 return om.get().getClassLoader(); 852 } else { 853 throw new IllegalArgumentException("Module " + name 854 + " not known to this layer"); 855 } 856 } 857 858 /** 859 * Returns a string describing this layer. 860 * 861 * @return A possibly empty string describing this layer 862 */ 863 @Override 864 public String toString() { 865 return modules().stream() 866 .map(Module::getName) 867 .collect(Collectors.joining(", ")); 868 } 869 870 /** 871 * Returns the <em>empty</em> layer. There are no modules in the empty 872 * layer. It has no parents. 873 * 874 * @return The empty layer 875 */ 876 public static Layer empty() { 877 return EMPTY_LAYER; 878 } 879 880 881 /** 882 * Returns the boot layer. The boot layer contains at least one module, 883 * {@code java.base}. Its parent is the {@link #empty() empty} layer. 884 * 885 * @apiNote This method returns {@code null} during startup and before 886 * the boot layer is fully initialized. 887 * 888 * @return The boot layer 889 */ 890 public static Layer boot() { 891 return SharedSecrets.getJavaLangAccess().getBootLayer(); 892 } 893 894 895 /** 896 * Returns the ServicesCatalog for this Layer, creating it if not 897 * already created. 898 */ 899 ServicesCatalog getServicesCatalog() { 900 ServicesCatalog servicesCatalog = this.servicesCatalog; 901 if (servicesCatalog != null) 902 return servicesCatalog; 903 904 synchronized (this) { 905 servicesCatalog = this.servicesCatalog; 906 if (servicesCatalog == null) { 907 servicesCatalog = ServicesCatalog.create(); 908 nameToModule.values().forEach(servicesCatalog::register); 909 this.servicesCatalog = servicesCatalog; 910 } 911 } 912 913 return servicesCatalog; 914 } 915 916 private volatile ServicesCatalog servicesCatalog; 917 918 919 /** 920 * Record that this layer has at least one module defined to the given 921 * class loader. 922 */ 923 void bindToLoader(ClassLoader loader) { 924 // CLV.computeIfAbsent(loader, (cl, clv) -> new CopyOnWriteArrayList<>()) 925 List<Layer> list = CLV.get(loader); 926 if (list == null) { 927 list = new CopyOnWriteArrayList<>(); 928 List<Layer> previous = CLV.putIfAbsent(loader, list); 929 if (previous != null) list = previous; 930 } 931 list.add(this); 932 } 933 934 /** 935 * Returns a stream of the layers that have at least one module defined to 936 * the given class loader. 937 */ 938 static Stream<Layer> layers(ClassLoader loader) { 939 List<Layer> list = CLV.get(loader); 940 if (list != null) { 941 return list.stream(); 942 } else { 943 return Stream.empty(); 944 } 945 } 946 947 // the list of layers with modules defined to a class loader 948 private static final ClassLoaderValue<List<Layer>> CLV = new ClassLoaderValue<>(); 949 }