< prev index next >

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

Print this page




 289         // mapping of modules to class loaders
 290         Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
 291 
 292         // check that all modules to be mapped to the boot loader will be
 293         // loaded from the runtime image
 294         if (needPostResolutionChecks) {
 295             for (ResolvedModule resolvedModule : cf.modules()) {
 296                 ModuleReference mref = resolvedModule.reference();
 297                 String name = mref.descriptor().name();
 298                 ClassLoader cl = clf.apply(name);
 299                 if (cl == null) {
 300 
 301                     if (upgradeModulePath != null
 302                             && upgradeModulePath.find(name).isPresent())
 303                         fail(name + ": cannot be loaded from upgrade module path");
 304 
 305                     if (!systemModules.find(name).isPresent())
 306                         fail(name + ": cannot be loaded from application module path");
 307                 }
 308             }







 309         }
 310 
 311 
 312         long t4 = System.nanoTime();
 313 
 314         // define modules to VM/runtime
 315         Layer bootLayer = Layer.empty().defineModules(cf, clf);
 316 
 317         PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
 318 
 319 
 320         long t5 = System.nanoTime();
 321 
 322         // define the module to its class loader, except java.base
 323         for (ResolvedModule resolvedModule : cf.modules()) {
 324             ModuleReference mref = resolvedModule.reference();
 325             String name = mref.descriptor().name();
 326             ClassLoader cl = clf.apply(name);
 327             if (cl == null) {
 328                 if (!name.equals(JAVA_BASE)) BootLoader.loadModule(mref);


 447         return modules;
 448     }
 449 
 450     /**
 451      * Process the --add-reads options to add any additional read edges that
 452      * are specified on the command-line.
 453      */
 454     private static void addExtraReads(Layer bootLayer) {
 455 
 456         // decode the command line options
 457         Map<String, List<String>> map = decode("jdk.module.addreads.");
 458         if (map.isEmpty())
 459             return;
 460 
 461         for (Map.Entry<String, List<String>> e : map.entrySet()) {
 462 
 463             // the key is $MODULE
 464             String mn = e.getKey();
 465             Optional<Module> om = bootLayer.findModule(mn);
 466             if (!om.isPresent()) {
 467                 warn("Unknown module: " + mn);
 468                 continue;
 469             }
 470             Module m = om.get();
 471 
 472             // the value is the set of other modules (by name)
 473             for (String name : e.getValue()) {
 474                 if (ALL_UNNAMED.equals(name)) {
 475                     Modules.addReadsAllUnnamed(m);
 476                 } else {
 477                     om = bootLayer.findModule(name);
 478                     if (om.isPresent()) {
 479                         Modules.addReads(m, om.get());
 480                     } else {
 481                         warn("Unknown module: " + name);
 482                     }
 483                 }
 484             }
 485         }
 486     }
 487 
 488     /**
 489      * Process the --add-exports and --add-opens options to export/open
 490      * additional packages specified on the command-line.
 491      */
 492     private static void addExtraExportsAndOpens(Layer bootLayer) {
 493 
 494         // --add-exports
 495         String prefix = "jdk.module.addexports.";
 496         Map<String, List<String>> extraExports = decode(prefix);
 497         if (!extraExports.isEmpty()) {
 498             addExtraExportsOrOpens(bootLayer, extraExports, false);
 499         }
 500 
 501         // --add-opens
 502         prefix = "jdk.module.addopens.";
 503         Map<String, List<String>> extraOpens = decode(prefix);
 504         if (!extraOpens.isEmpty()) {
 505             addExtraExportsOrOpens(bootLayer, extraOpens, true);
 506         }
 507     }
 508 
 509     private static void addExtraExportsOrOpens(Layer bootLayer,
 510                                                Map<String, List<String>> map,
 511                                                boolean opens)
 512     {

 513         for (Map.Entry<String, List<String>> e : map.entrySet()) {
 514 
 515             // the key is $MODULE/$PACKAGE
 516             String key = e.getKey();
 517             String[] s = key.split("/");
 518             if (s.length != 2)
 519                 fail("Unable to parse as <module>/<package>: " + key);
 520 
 521             String mn = s[0];
 522             String pn = s[1];
 523             if (mn.isEmpty() || pn.isEmpty())
 524                 fail("Module and package name must be specified: " + key);
 525 
 526             // The exporting module is in the boot layer
 527             Module m;
 528             Optional<Module> om = bootLayer.findModule(mn);
 529             if (!om.isPresent()) {
 530                 warn("Unknown module: " + mn);
 531                 continue;
 532             }
 533 
 534             m = om.get();
 535 
 536             if (!m.getDescriptor().packages().contains(pn)) {
 537                 warn("package " + pn + " not in " + mn);
 538                 continue;
 539             }
 540 
 541             // the value is the set of modules to export to (by name)
 542             for (String name : e.getValue()) {
 543                 boolean allUnnamed = false;
 544                 Module other = null;
 545                 if (ALL_UNNAMED.equals(name)) {
 546                     allUnnamed = true;
 547                 } else {
 548                     om = bootLayer.findModule(name);
 549                     if (om.isPresent()) {
 550                         other = om.get();
 551                     } else {
 552                         warn("Unknown module: " + name);
 553                         continue;
 554                     }
 555                 }
 556                 if (allUnnamed) {
 557                     if (opens) {
 558                         Modules.addOpensToAllUnnamed(m, pn);
 559                     } else {
 560                         Modules.addExportsToAllUnnamed(m, pn);
 561                     }
 562                 } else {
 563                     if (opens) {
 564                         Modules.addOpens(m, pn, other);
 565                     } else {
 566                         Modules.addExports(m, pn, other);
 567                     }
 568                 }
 569 
 570             }
 571         }
 572     }


 576      * --patch-modules options that are encoded in system properties.
 577      *
 578      * @param prefix the system property prefix
 579      * @praam regex the regex for splitting the RHS of the option value
 580      */
 581     private static Map<String, List<String>> decode(String prefix,
 582                                                     String regex,
 583                                                     boolean allowDuplicates) {
 584         int index = 0;
 585         // the system property is removed after decoding
 586         String value = getAndRemoveProperty(prefix + index);
 587         if (value == null)
 588             return Collections.emptyMap();
 589 
 590         Map<String, List<String>> map = new HashMap<>();
 591 
 592         while (value != null) {
 593 
 594             int pos = value.indexOf('=');
 595             if (pos == -1)
 596                 fail("Unable to parse as <module>=<value>: " + value);
 597             if (pos == 0)
 598                 fail("Missing module name in: " + value);
 599 
 600             // key is <module> or <module>/<package>
 601             String key = value.substring(0, pos);
 602 
 603             String rhs = value.substring(pos+1);
 604             if (rhs.isEmpty())
 605                 fail("Unable to parse as <module>=<value>: " + value);
 606 
 607             // value is <module>(,<module>)* or <file>(<pathsep><file>)*
 608             if (!allowDuplicates && map.containsKey(key))
 609                 fail(key + " specified more than once");
 610             List<String> values = map.computeIfAbsent(key, k -> new ArrayList<>());

 611             for (String s : rhs.split(regex)) {
 612                 if (s.length() > 0) values.add(s);


 613             }



 614 
 615             index++;
 616             value = getAndRemoveProperty(prefix + index);
 617         }
 618 
 619         return map;
 620     }
 621 
 622     /**
 623      * Decodes the values of --add-reads, -add-exports or --add-opens
 624      * which use the "," to separate the RHS of the option value.
 625      */
 626     private static Map<String, List<String>> decode(String prefix) {
 627         return decode(prefix, ",", true);
 628     }
 629 
 630     /**
 631      * Gets and remove the named system property
 632      */
 633     private static String getAndRemoveProperty(String key) {


 655                 } else {
 656                     incubating += ", " + mn;
 657                 }
 658             }
 659         }
 660         if (incubating != null)
 661             warn("Using incubator modules: " + incubating);
 662     }
 663 
 664     /**
 665      * Throws a RuntimeException with the given message
 666      */
 667     static void fail(String m) {
 668         throw new RuntimeException(m);
 669     }
 670 
 671     static void warn(String m) {
 672         System.err.println("WARNING: " + m);
 673     }
 674 




































 675     static class PerfCounters {
 676 
 677         static PerfCounter systemModulesTime
 678             = PerfCounter.newPerfCounter("jdk.module.bootstrap.systemModulesTime");
 679         static PerfCounter defineBaseTime
 680             = PerfCounter.newPerfCounter("jdk.module.bootstrap.defineBaseTime");
 681         static PerfCounter optionsAndRootsTime
 682             = PerfCounter.newPerfCounter("jdk.module.bootstrap.optionsAndRootsTime");
 683         static PerfCounter resolveTime
 684             = PerfCounter.newPerfCounter("jdk.module.bootstrap.resolveTime");
 685         static PerfCounter layerCreateTime
 686             = PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
 687         static PerfCounter loadModulesTime
 688             = PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
 689         static PerfCounter bootstrapTime
 690             = PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
 691     }
 692 }


 289         // mapping of modules to class loaders
 290         Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
 291 
 292         // check that all modules to be mapped to the boot loader will be
 293         // loaded from the runtime image
 294         if (needPostResolutionChecks) {
 295             for (ResolvedModule resolvedModule : cf.modules()) {
 296                 ModuleReference mref = resolvedModule.reference();
 297                 String name = mref.descriptor().name();
 298                 ClassLoader cl = clf.apply(name);
 299                 if (cl == null) {
 300 
 301                     if (upgradeModulePath != null
 302                             && upgradeModulePath.find(name).isPresent())
 303                         fail(name + ": cannot be loaded from upgrade module path");
 304 
 305                     if (!systemModules.find(name).isPresent())
 306                         fail(name + ": cannot be loaded from application module path");
 307                 }
 308             }
 309 
 310             // check if module specified in --patch-module is present
 311             for (String mn: patcher.patchedModules()) {
 312                 if (!cf.findModule(mn).isPresent()) {
 313                     warnUnknownModule(PATCH_MODULE, mn);
 314                 }
 315             }
 316         }
 317 
 318 
 319         long t4 = System.nanoTime();
 320 
 321         // define modules to VM/runtime
 322         Layer bootLayer = Layer.empty().defineModules(cf, clf);
 323 
 324         PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
 325 
 326 
 327         long t5 = System.nanoTime();
 328 
 329         // define the module to its class loader, except java.base
 330         for (ResolvedModule resolvedModule : cf.modules()) {
 331             ModuleReference mref = resolvedModule.reference();
 332             String name = mref.descriptor().name();
 333             ClassLoader cl = clf.apply(name);
 334             if (cl == null) {
 335                 if (!name.equals(JAVA_BASE)) BootLoader.loadModule(mref);


 454         return modules;
 455     }
 456 
 457     /**
 458      * Process the --add-reads options to add any additional read edges that
 459      * are specified on the command-line.
 460      */
 461     private static void addExtraReads(Layer bootLayer) {
 462 
 463         // decode the command line options
 464         Map<String, List<String>> map = decode("jdk.module.addreads.");
 465         if (map.isEmpty())
 466             return;
 467 
 468         for (Map.Entry<String, List<String>> e : map.entrySet()) {
 469 
 470             // the key is $MODULE
 471             String mn = e.getKey();
 472             Optional<Module> om = bootLayer.findModule(mn);
 473             if (!om.isPresent()) {
 474                 warnUnknownModule(ADD_READS, mn);
 475                 continue;
 476             }
 477             Module m = om.get();
 478 
 479             // the value is the set of other modules (by name)
 480             for (String name : e.getValue()) {
 481                 if (ALL_UNNAMED.equals(name)) {
 482                     Modules.addReadsAllUnnamed(m);
 483                 } else {
 484                     om = bootLayer.findModule(name);
 485                     if (om.isPresent()) {
 486                         Modules.addReads(m, om.get());
 487                     } else {
 488                         warnUnknownModule(ADD_READS, name);
 489                     }
 490                 }
 491             }
 492         }
 493     }
 494 
 495     /**
 496      * Process the --add-exports and --add-opens options to export/open
 497      * additional packages specified on the command-line.
 498      */
 499     private static void addExtraExportsAndOpens(Layer bootLayer) {
 500 
 501         // --add-exports
 502         String prefix = "jdk.module.addexports.";
 503         Map<String, List<String>> extraExports = decode(prefix);
 504         if (!extraExports.isEmpty()) {
 505             addExtraExportsOrOpens(bootLayer, extraExports, false);
 506         }
 507 
 508         // --add-opens
 509         prefix = "jdk.module.addopens.";
 510         Map<String, List<String>> extraOpens = decode(prefix);
 511         if (!extraOpens.isEmpty()) {
 512             addExtraExportsOrOpens(bootLayer, extraOpens, true);
 513         }
 514     }
 515 
 516     private static void addExtraExportsOrOpens(Layer bootLayer,
 517                                                Map<String, List<String>> map,
 518                                                boolean opens)
 519     {
 520         String option = opens ? ADD_OPENS : ADD_EXPORTS;
 521         for (Map.Entry<String, List<String>> e : map.entrySet()) {
 522 
 523             // the key is $MODULE/$PACKAGE
 524             String key = e.getKey();
 525             String[] s = key.split("/");
 526             if (s.length != 2)
 527                 fail(unableToParse(option,  "<module>/<package>", key));
 528 
 529             String mn = s[0];
 530             String pn = s[1];
 531             if (mn.isEmpty() || pn.isEmpty())
 532                 fail(unableToParse(option,  "<module>/<package>", key));
 533 
 534             // The exporting module is in the boot layer
 535             Module m;
 536             Optional<Module> om = bootLayer.findModule(mn);
 537             if (!om.isPresent()) {
 538                 warnUnknownModule(option, mn);
 539                 continue;
 540             }
 541 
 542             m = om.get();
 543 
 544             if (!m.getDescriptor().packages().contains(pn)) {
 545                 warn("package " + pn + " not in " + mn);
 546                 continue;
 547             }
 548 
 549             // the value is the set of modules to export to (by name)
 550             for (String name : e.getValue()) {
 551                 boolean allUnnamed = false;
 552                 Module other = null;
 553                 if (ALL_UNNAMED.equals(name)) {
 554                     allUnnamed = true;
 555                 } else {
 556                     om = bootLayer.findModule(name);
 557                     if (om.isPresent()) {
 558                         other = om.get();
 559                     } else {
 560                         warnUnknownModule(option, name);
 561                         continue;
 562                     }
 563                 }
 564                 if (allUnnamed) {
 565                     if (opens) {
 566                         Modules.addOpensToAllUnnamed(m, pn);
 567                     } else {
 568                         Modules.addExportsToAllUnnamed(m, pn);
 569                     }
 570                 } else {
 571                     if (opens) {
 572                         Modules.addOpens(m, pn, other);
 573                     } else {
 574                         Modules.addExports(m, pn, other);
 575                     }
 576                 }
 577 
 578             }
 579         }
 580     }


 584      * --patch-modules options that are encoded in system properties.
 585      *
 586      * @param prefix the system property prefix
 587      * @praam regex the regex for splitting the RHS of the option value
 588      */
 589     private static Map<String, List<String>> decode(String prefix,
 590                                                     String regex,
 591                                                     boolean allowDuplicates) {
 592         int index = 0;
 593         // the system property is removed after decoding
 594         String value = getAndRemoveProperty(prefix + index);
 595         if (value == null)
 596             return Collections.emptyMap();
 597 
 598         Map<String, List<String>> map = new HashMap<>();
 599 
 600         while (value != null) {
 601 
 602             int pos = value.indexOf('=');
 603             if (pos == -1)
 604                 fail(unableToParse(option(prefix), "<module>=<value>", value));
 605             if (pos == 0)
 606                 fail(unableToParse(option(prefix), "<module>=<value>", value));
 607 
 608             // key is <module> or <module>/<package>
 609             String key = value.substring(0, pos);
 610 
 611             String rhs = value.substring(pos+1);
 612             if (rhs.isEmpty())
 613                 fail(unableToParse(option(prefix), "<module>=<value>", value));
 614 
 615             // value is <module>(,<module>)* or <file>(<pathsep><file>)*
 616             if (!allowDuplicates && map.containsKey(key))
 617                 fail(key + " specified more than once in " + option(prefix));
 618             List<String> values = map.computeIfAbsent(key, k -> new ArrayList<>());
 619             int ntargets = 0;
 620             for (String s : rhs.split(regex)) {
 621                 if (s.length() > 0) {
 622                     values.add(s);
 623                     ntargets++;
 624                 }
 625             }
 626             if (ntargets == 0)
 627                 fail("Target must be specified: " + option(prefix) + " " + value);
 628 
 629             index++;
 630             value = getAndRemoveProperty(prefix + index);
 631         }
 632 
 633         return map;
 634     }
 635 
 636     /**
 637      * Decodes the values of --add-reads, -add-exports or --add-opens
 638      * which use the "," to separate the RHS of the option value.
 639      */
 640     private static Map<String, List<String>> decode(String prefix) {
 641         return decode(prefix, ",", true);
 642     }
 643 
 644     /**
 645      * Gets and remove the named system property
 646      */
 647     private static String getAndRemoveProperty(String key) {


 669                 } else {
 670                     incubating += ", " + mn;
 671                 }
 672             }
 673         }
 674         if (incubating != null)
 675             warn("Using incubator modules: " + incubating);
 676     }
 677 
 678     /**
 679      * Throws a RuntimeException with the given message
 680      */
 681     static void fail(String m) {
 682         throw new RuntimeException(m);
 683     }
 684 
 685     static void warn(String m) {
 686         System.err.println("WARNING: " + m);
 687     }
 688 
 689     static void warnUnknownModule(String option, String mn) {
 690         warn("Unknown module: " + mn + " specified in " + option);
 691     }
 692 
 693     static String unableToParse(String option, String text, String value) {
 694         return "Unable to parse " +  option + " " + text + ": " + value;
 695     }
 696 
 697     private static final String ADD_MODULES  = "--add-modules";
 698     private static final String ADD_EXPORTS  = "--add-exports";
 699     private static final String ADD_OPENS    = "--add-opens";
 700     private static final String ADD_READS    = "--add-reads";
 701     private static final String PATCH_MODULE = "--patch-module";
 702 
 703 
 704     /*
 705      * Returns the command-line option name corresponds to the specified
 706      * system property prefix.
 707      */
 708     static String option(String prefix) {
 709         switch (prefix) {
 710             case "jdk.module.addexports.":
 711                 return ADD_EXPORTS;
 712             case "jdk.module.addopens.":
 713                 return ADD_OPENS;
 714             case "jdk.module.addreads.":
 715                 return ADD_READS;
 716             case "jdk.module.patch.":
 717                 return PATCH_MODULE;
 718             case "jdk.module.addmods.":
 719                 return ADD_MODULES;
 720             default:
 721                 throw new IllegalArgumentException(prefix);
 722         }
 723     }
 724 
 725     static class PerfCounters {
 726 
 727         static PerfCounter systemModulesTime
 728             = PerfCounter.newPerfCounter("jdk.module.bootstrap.systemModulesTime");
 729         static PerfCounter defineBaseTime
 730             = PerfCounter.newPerfCounter("jdk.module.bootstrap.defineBaseTime");
 731         static PerfCounter optionsAndRootsTime
 732             = PerfCounter.newPerfCounter("jdk.module.bootstrap.optionsAndRootsTime");
 733         static PerfCounter resolveTime
 734             = PerfCounter.newPerfCounter("jdk.module.bootstrap.resolveTime");
 735         static PerfCounter layerCreateTime
 736             = PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
 737         static PerfCounter loadModulesTime
 738             = PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
 739         static PerfCounter bootstrapTime
 740             = PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
 741     }
 742 }
< prev index next >