< prev index next >

src/java.base/share/classes/java/lang/Module.java

Print this page




 109     private final ModuleDescriptor descriptor;
 110 
 111 
 112     /**
 113      * Creates a new named Module. The resulting Module will be defined to the
 114      * VM but will not read any other modules, will not have any exports setup
 115      * and will not be registered in the service catalog.
 116      */
 117     Module(ModuleLayer layer,
 118            ClassLoader loader,
 119            ModuleDescriptor descriptor,
 120            URI uri)
 121     {
 122         this.layer = layer;
 123         this.name = descriptor.name();
 124         this.loader = loader;
 125         this.descriptor = descriptor;
 126 
 127         // define module to VM
 128 
 129         boolean isOpen = descriptor.isOpen();
 130         Version version = descriptor.version().orElse(null);
 131         String vs = Objects.toString(version, null);
 132         String loc = Objects.toString(uri, null);
 133         String[] packages = descriptor.packages().toArray(new String[0]);
 134         defineModule0(this, isOpen, vs, loc, packages);
 135     }
 136 
 137 
 138     /**
 139      * Create the unnamed Module for the given ClassLoader.
 140      *
 141      * @see ClassLoader#getUnnamedModule
 142      */
 143     Module(ClassLoader loader) {
 144         this.layer = null;
 145         this.name = null;
 146         this.loader = loader;
 147         this.descriptor = null;
 148     }
 149 


1025             if (c == '/' || c == ';' || c == '[') {
1026                 throw new IllegalArgumentException("Illegal character: " + c);
1027             }
1028         }
1029 
1030         // create extraPackages if needed
1031         Map<String, Boolean> extraPackages = this.extraPackages;
1032         if (extraPackages == null) {
1033             synchronized (this) {
1034                 extraPackages = this.extraPackages;
1035                 if (extraPackages == null)
1036                     this.extraPackages = extraPackages = new ConcurrentHashMap<>();
1037             }
1038         }
1039 
1040         // update VM first in case it fails. This is a no-op if another thread
1041         // beats us to add the package first
1042         if (syncVM) {
1043             // throws IllegalStateException if defined to another module
1044             addPackage0(this, pn);
1045             if (descriptor.isOpen() || descriptor.isAutomatic()) {
1046                 addExportsToAll0(this, pn);
1047             }
1048         }
1049         extraPackages.putIfAbsent(pn, Boolean.TRUE);
1050     }
1051 
1052 
1053     // -- creating Module objects --
1054 
1055     /**
1056      * Defines all module in a configuration to the runtime.
1057      *
1058      * @return a map of module name to runtime {@code Module}
1059      *
1060      * @throws IllegalArgumentException
1061      *         If defining any of the modules to the VM fails
1062      */
1063     static Map<String, Module> defineModules(Configuration cf,
1064                                              Function<String, ClassLoader> clf,
1065                                              ModuleLayer layer)
1066     {
1067         Map<String, Module> nameToModule = new HashMap<>();


1128                         if (m2 != null)
1129                             break;
1130                     }
1131                     assert m2 != null;
1132                     if (nameToSource.isEmpty())
1133                         nameToSource = new HashMap<>();
1134                     nameToSource.put(other.name(), m2);
1135                 }
1136                 reads.add(m2);
1137 
1138                 // update VM view
1139                 addReads0(m, m2);
1140             }
1141             m.reads = reads;
1142 
1143             // automatic modules read all unnamed modules
1144             if (descriptor.isAutomatic()) {
1145                 m.implAddReads(ALL_UNNAMED_MODULE, true);
1146             }
1147 
1148             // exports and opens


1149             initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
1150         }

1151 
1152         // register the modules in the boot layer
1153         if (isBootLayer) {
1154             for (ResolvedModule resolvedModule : cf.modules()) {
1155                 ModuleReference mref = resolvedModule.reference();
1156                 ModuleDescriptor descriptor = mref.descriptor();
1157                 if (!descriptor.provides().isEmpty()) {
1158                     String name = descriptor.name();
1159                     Module m = nameToModule.get(name);
1160                     ClassLoader loader = moduleToLoader.get(name);
1161                     ServicesCatalog catalog;
1162                     if (loader == null) {
1163                         catalog = BootLoader.getServicesCatalog();
1164                     } else {
1165                         catalog = ServicesCatalog.getServicesCatalog(loader);
1166                     }
1167                     catalog.register(m);
1168                 }
1169             }
1170         }


1190                 .filter(l -> l.configuration() == cf)
1191                 .findAny()
1192                 .map(layer -> {
1193                     Optional<Module> om = layer.findModule(dn);
1194                     assert om.isPresent() : dn + " not found in layer";
1195                     Module m = om.get();
1196                     assert m.getLayer() == layer : m + " not in expected layer";
1197                     return m;
1198                 })
1199                 .orElse(null);
1200     }
1201 
1202 
1203     /**
1204      * Initialize the maps of exported and open packages for module m.
1205      */
1206     private static void initExportsAndOpens(Module m,
1207                                             Map<String, Module> nameToSource,
1208                                             Map<String, Module> nameToModule,
1209                                             List<ModuleLayer> parents) {
1210         // The VM doesn't special case open or automatic modules so need to
1211         // export all packages
1212         ModuleDescriptor descriptor = m.getDescriptor();
1213         if (descriptor.isOpen() || descriptor.isAutomatic()) {
1214             assert descriptor.opens().isEmpty();
1215             for (String source : descriptor.packages()) {
1216                 addExportsToAll0(m, source);
1217             }
1218             return;
1219         }
1220 
1221         Map<String, Set<Module>> openPackages = new HashMap<>();
1222         Map<String, Set<Module>> exportedPackages = new HashMap<>();
1223 
1224         // process the open packages first

1225         for (Opens opens : descriptor.opens()) {
1226             String source = opens.source();
1227 
1228             if (opens.isQualified()) {
1229                 // qualified opens
1230                 Set<Module> targets = new HashSet<>();
1231                 for (String target : opens.targets()) {
1232                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
1233                     if (m2 != null) {
1234                         addExports0(m, source, m2);
1235                         targets.add(m2);
1236                     }
1237                 }
1238                 if (!targets.isEmpty()) {
1239                     openPackages.put(source, targets);
1240                 }
1241             } else {
1242                 // unqualified opens
1243                 addExportsToAll0(m, source);
1244                 openPackages.put(source, EVERYONE_SET);




 109     private final ModuleDescriptor descriptor;
 110 
 111 
 112     /**
 113      * Creates a new named Module. The resulting Module will be defined to the
 114      * VM but will not read any other modules, will not have any exports setup
 115      * and will not be registered in the service catalog.
 116      */
 117     Module(ModuleLayer layer,
 118            ClassLoader loader,
 119            ModuleDescriptor descriptor,
 120            URI uri)
 121     {
 122         this.layer = layer;
 123         this.name = descriptor.name();
 124         this.loader = loader;
 125         this.descriptor = descriptor;
 126 
 127         // define module to VM
 128 
 129         boolean isOpen = descriptor.isOpen() || descriptor.isAutomatic();
 130         Version version = descriptor.version().orElse(null);
 131         String vs = Objects.toString(version, null);
 132         String loc = Objects.toString(uri, null);
 133         String[] packages = descriptor.packages().toArray(new String[0]);
 134         defineModule0(this, isOpen, vs, loc, packages);
 135     }
 136 
 137 
 138     /**
 139      * Create the unnamed Module for the given ClassLoader.
 140      *
 141      * @see ClassLoader#getUnnamedModule
 142      */
 143     Module(ClassLoader loader) {
 144         this.layer = null;
 145         this.name = null;
 146         this.loader = loader;
 147         this.descriptor = null;
 148     }
 149 


1025             if (c == '/' || c == ';' || c == '[') {
1026                 throw new IllegalArgumentException("Illegal character: " + c);
1027             }
1028         }
1029 
1030         // create extraPackages if needed
1031         Map<String, Boolean> extraPackages = this.extraPackages;
1032         if (extraPackages == null) {
1033             synchronized (this) {
1034                 extraPackages = this.extraPackages;
1035                 if (extraPackages == null)
1036                     this.extraPackages = extraPackages = new ConcurrentHashMap<>();
1037             }
1038         }
1039 
1040         // update VM first in case it fails. This is a no-op if another thread
1041         // beats us to add the package first
1042         if (syncVM) {
1043             // throws IllegalStateException if defined to another module
1044             addPackage0(this, pn);



1045         }
1046         extraPackages.putIfAbsent(pn, Boolean.TRUE);
1047     }
1048 
1049 
1050     // -- creating Module objects --
1051 
1052     /**
1053      * Defines all module in a configuration to the runtime.
1054      *
1055      * @return a map of module name to runtime {@code Module}
1056      *
1057      * @throws IllegalArgumentException
1058      *         If defining any of the modules to the VM fails
1059      */
1060     static Map<String, Module> defineModules(Configuration cf,
1061                                              Function<String, ClassLoader> clf,
1062                                              ModuleLayer layer)
1063     {
1064         Map<String, Module> nameToModule = new HashMap<>();


1125                         if (m2 != null)
1126                             break;
1127                     }
1128                     assert m2 != null;
1129                     if (nameToSource.isEmpty())
1130                         nameToSource = new HashMap<>();
1131                     nameToSource.put(other.name(), m2);
1132                 }
1133                 reads.add(m2);
1134 
1135                 // update VM view
1136                 addReads0(m, m2);
1137             }
1138             m.reads = reads;
1139 
1140             // automatic modules read all unnamed modules
1141             if (descriptor.isAutomatic()) {
1142                 m.implAddReads(ALL_UNNAMED_MODULE, true);
1143             }
1144 
1145             // export and open packages, skipped for open and automatic
1146             // modules since they are treated as if all packages are open
1147             if (!descriptor.isOpen() && !descriptor.isAutomatic()) { 
1148                 initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
1149             }
1150         }
1151 
1152         // register the modules in the boot layer
1153         if (isBootLayer) {
1154             for (ResolvedModule resolvedModule : cf.modules()) {
1155                 ModuleReference mref = resolvedModule.reference();
1156                 ModuleDescriptor descriptor = mref.descriptor();
1157                 if (!descriptor.provides().isEmpty()) {
1158                     String name = descriptor.name();
1159                     Module m = nameToModule.get(name);
1160                     ClassLoader loader = moduleToLoader.get(name);
1161                     ServicesCatalog catalog;
1162                     if (loader == null) {
1163                         catalog = BootLoader.getServicesCatalog();
1164                     } else {
1165                         catalog = ServicesCatalog.getServicesCatalog(loader);
1166                     }
1167                     catalog.register(m);
1168                 }
1169             }
1170         }


1190                 .filter(l -> l.configuration() == cf)
1191                 .findAny()
1192                 .map(layer -> {
1193                     Optional<Module> om = layer.findModule(dn);
1194                     assert om.isPresent() : dn + " not found in layer";
1195                     Module m = om.get();
1196                     assert m.getLayer() == layer : m + " not in expected layer";
1197                     return m;
1198                 })
1199                 .orElse(null);
1200     }
1201 
1202 
1203     /**
1204      * Initialize the maps of exported and open packages for module m.
1205      */
1206     private static void initExportsAndOpens(Module m,
1207                                             Map<String, Module> nameToSource,
1208                                             Map<String, Module> nameToModule,
1209                                             List<ModuleLayer> parents) {











1210         Map<String, Set<Module>> openPackages = new HashMap<>();
1211         Map<String, Set<Module>> exportedPackages = new HashMap<>();
1212 
1213         // process the open packages first
1214         ModuleDescriptor descriptor = m.getDescriptor();
1215         for (Opens opens : descriptor.opens()) {
1216             String source = opens.source();
1217 
1218             if (opens.isQualified()) {
1219                 // qualified opens
1220                 Set<Module> targets = new HashSet<>();
1221                 for (String target : opens.targets()) {
1222                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
1223                     if (m2 != null) {
1224                         addExports0(m, source, m2);
1225                         targets.add(m2);
1226                     }
1227                 }
1228                 if (!targets.isEmpty()) {
1229                     openPackages.put(source, targets);
1230                 }
1231             } else {
1232                 // unqualified opens
1233                 addExportsToAll0(m, source);
1234                 openPackages.put(source, EVERYONE_SET);


< prev index next >