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
460 * Returns {@code true} if this module has <em>opened</em> a package to at
461 * least the given module.
462 *
463 * <p> This method returns {@code true} if invoked to test if a package in
464 * this module is open to itself. It returns {@code true} when invoked on an
465 * {@link ModuleDescriptor#isOpen open} module with a package in the module.
466 * It always returns {@code true} when invoked on an unnamed module. </p>
467 *
468 * <p> This method does not check if the given module reads this module. </p>
469 *
470 * @param pn
471 * The package name
472 * @param other
473 * The other module
474 *
475 * @return {@code true} if this module has <em>opened</em> the package
476 * to at least the given module
477 *
478 * @see ModuleDescriptor#opens()
479 * @see #addOpens(String,Module)
480 * @see AccessibleObject#setAccessible(boolean)
481 * @see java.lang.invoke.MethodHandles#privateLookupIn
482 */
483 public boolean isOpen(String pn, Module other) {
484 Objects.requireNonNull(pn);
485 Objects.requireNonNull(other);
486 return implIsExportedOrOpen(pn, other, /*open*/true);
487 }
488
489 /**
490 * Returns {@code true} if this module exports the given package
491 * unconditionally.
492 *
493 * <p> This method always returns {@code true} when invoked on an unnamed
494 * module. A package that is {@link #isOpen(String) opened} unconditionally
495 * is considered exported unconditionally at run-time and so this method
496 * returns {@code true} if the package is opened unconditionally. </p>
497 *
498 * <p> This method does not check if the given module reads this module. </p>
499 *
500 * @param pn
730 * module</em> but where the reflective access to the members of classes in
731 * the consumer module is delegated to code in another module. Code in the
732 * API module can use this method to open the package in the consumer module
733 * to the other module.
734 *
735 * @param pn
736 * The package name
737 * @param other
738 * The module
739 *
740 * @return this module
741 *
742 * @throws IllegalArgumentException
743 * If {@code pn} is {@code null}, or this is a named module and the
744 * package {@code pn} is not a package in this module
745 * @throws IllegalCallerException
746 * If this is a named module and this module has not opened the
747 * package to at least the caller's module
748 *
749 * @see #isOpen(String,Module)
750 * @see AccessibleObject#setAccessible(boolean)
751 * @see java.lang.invoke.MethodHandles#privateLookupIn
752 */
753 @CallerSensitive
754 public Module addOpens(String pn, Module other) {
755 if (pn == null)
756 throw new IllegalArgumentException("package is null");
757 Objects.requireNonNull(other);
758
759 if (isNamed()) {
760 Module caller = getCallerModule(Reflection.getCallerClass());
761 if (caller != this && (caller == null || !isOpen(pn, caller)))
762 throw new IllegalCallerException(pn + " is not open to " + caller);
763 implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
764 }
765
766 return this;
767 }
768
769
770 /**
1044 // unnamed module
1045 Stream<Package> packages;
1046 if (loader == null) {
1047 packages = BootLoader.packages();
1048 } else {
1049 packages = loader.packages();
1050 }
1051 return packages.map(Package::getName).collect(Collectors.toSet());
1052 }
1053 }
1054
1055
1056 // -- creating Module objects --
1057
1058 /**
1059 * Defines all module in a configuration to the runtime.
1060 *
1061 * @return a map of module name to runtime {@code Module}
1062 *
1063 * @throws IllegalArgumentException
1064 * If defining any of the modules to the VM fails
1065 */
1066 static Map<String, Module> defineModules(Configuration cf,
1067 Function<String, ClassLoader> clf,
1068 ModuleLayer layer)
1069 {
1070 boolean isBootLayer = (ModuleLayer.boot() == null);
1071
1072 int cap = (int)(cf.modules().size() / 0.75f + 1.0f);
1073 Map<String, Module> nameToModule = new HashMap<>(cap);
1074 Map<String, ClassLoader> nameToLoader = new HashMap<>(cap);
1075
1076 Set<ClassLoader> loaders = new HashSet<>();
1077 boolean hasPlatformModules = false;
1078
1079 // map each module to a class loader
1080 for (ResolvedModule resolvedModule : cf.modules()) {
1081 String name = resolvedModule.name();
1082 ClassLoader loader = clf.apply(name);
1083 nameToLoader.put(name, loader);
1084 if (loader == null || loader == ClassLoaders.platformClassLoader()) {
|
1 /*
2 * Copyright (c) 2014, 2018, 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
460 * Returns {@code true} if this module has <em>opened</em> a package to at
461 * least the given module.
462 *
463 * <p> This method returns {@code true} if invoked to test if a package in
464 * this module is open to itself. It returns {@code true} when invoked on an
465 * {@link ModuleDescriptor#isOpen open} module with a package in the module.
466 * It always returns {@code true} when invoked on an unnamed module. </p>
467 *
468 * <p> This method does not check if the given module reads this module. </p>
469 *
470 * @param pn
471 * The package name
472 * @param other
473 * The other module
474 *
475 * @return {@code true} if this module has <em>opened</em> the package
476 * to at least the given module
477 *
478 * @see ModuleDescriptor#opens()
479 * @see #addOpens(String,Module)
480 * @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
481 * @see java.lang.invoke.MethodHandles#privateLookupIn
482 */
483 public boolean isOpen(String pn, Module other) {
484 Objects.requireNonNull(pn);
485 Objects.requireNonNull(other);
486 return implIsExportedOrOpen(pn, other, /*open*/true);
487 }
488
489 /**
490 * Returns {@code true} if this module exports the given package
491 * unconditionally.
492 *
493 * <p> This method always returns {@code true} when invoked on an unnamed
494 * module. A package that is {@link #isOpen(String) opened} unconditionally
495 * is considered exported unconditionally at run-time and so this method
496 * returns {@code true} if the package is opened unconditionally. </p>
497 *
498 * <p> This method does not check if the given module reads this module. </p>
499 *
500 * @param pn
730 * module</em> but where the reflective access to the members of classes in
731 * the consumer module is delegated to code in another module. Code in the
732 * API module can use this method to open the package in the consumer module
733 * to the other module.
734 *
735 * @param pn
736 * The package name
737 * @param other
738 * The module
739 *
740 * @return this module
741 *
742 * @throws IllegalArgumentException
743 * If {@code pn} is {@code null}, or this is a named module and the
744 * package {@code pn} is not a package in this module
745 * @throws IllegalCallerException
746 * If this is a named module and this module has not opened the
747 * package to at least the caller's module
748 *
749 * @see #isOpen(String,Module)
750 * @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
751 * @see java.lang.invoke.MethodHandles#privateLookupIn
752 */
753 @CallerSensitive
754 public Module addOpens(String pn, Module other) {
755 if (pn == null)
756 throw new IllegalArgumentException("package is null");
757 Objects.requireNonNull(other);
758
759 if (isNamed()) {
760 Module caller = getCallerModule(Reflection.getCallerClass());
761 if (caller != this && (caller == null || !isOpen(pn, caller)))
762 throw new IllegalCallerException(pn + " is not open to " + caller);
763 implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
764 }
765
766 return this;
767 }
768
769
770 /**
1044 // unnamed module
1045 Stream<Package> packages;
1046 if (loader == null) {
1047 packages = BootLoader.packages();
1048 } else {
1049 packages = loader.packages();
1050 }
1051 return packages.map(Package::getName).collect(Collectors.toSet());
1052 }
1053 }
1054
1055
1056 // -- creating Module objects --
1057
1058 /**
1059 * Defines all module in a configuration to the runtime.
1060 *
1061 * @return a map of module name to runtime {@code Module}
1062 *
1063 * @throws IllegalArgumentException
1064 * If the function maps a module to the null or platform class loader
1065 * @throws IllegalStateException
1066 * If the module cannot be defined to the VM or its packages overlap
1067 * with another module mapped to the same class loader
1068 */
1069 static Map<String, Module> defineModules(Configuration cf,
1070 Function<String, ClassLoader> clf,
1071 ModuleLayer layer)
1072 {
1073 boolean isBootLayer = (ModuleLayer.boot() == null);
1074
1075 int cap = (int)(cf.modules().size() / 0.75f + 1.0f);
1076 Map<String, Module> nameToModule = new HashMap<>(cap);
1077 Map<String, ClassLoader> nameToLoader = new HashMap<>(cap);
1078
1079 Set<ClassLoader> loaders = new HashSet<>();
1080 boolean hasPlatformModules = false;
1081
1082 // map each module to a class loader
1083 for (ResolvedModule resolvedModule : cf.modules()) {
1084 String name = resolvedModule.name();
1085 ClassLoader loader = clf.apply(name);
1086 nameToLoader.put(name, loader);
1087 if (loader == null || loader == ClassLoaders.platformClassLoader()) {
|