use of jdk.internal.module.ServicesCatalog in project Bytecoder by mirkosertic.
the class Module method defineModules.
// -- creating Module objects --
/**
* Defines all module in a configuration to the runtime.
*
* @return a map of module name to runtime {@code Module}
*
* @throws IllegalArgumentException
* If defining any of the modules to the VM fails
*/
static Map<String, Module> defineModules(Configuration cf, Function<String, ClassLoader> clf, ModuleLayer layer) {
boolean isBootLayer = (ModuleLayer.boot() == null);
int cap = (int) (cf.modules().size() / 0.75f + 1.0f);
Map<String, Module> nameToModule = new HashMap<>(cap);
Map<String, ClassLoader> nameToLoader = new HashMap<>(cap);
Set<ClassLoader> loaders = new HashSet<>();
boolean hasPlatformModules = false;
// map each module to a class loader
for (ResolvedModule resolvedModule : cf.modules()) {
String name = resolvedModule.name();
ClassLoader loader = clf.apply(name);
nameToLoader.put(name, loader);
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
if (!(clf instanceof ModuleLoaderMap.Mapper)) {
throw new IllegalArgumentException("loader can't be 'null'" + " or the platform class loader");
}
hasPlatformModules = true;
} else {
loaders.add(loader);
}
}
// define each module in the configuration to the VM
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
ModuleDescriptor descriptor = mref.descriptor();
String name = descriptor.name();
ClassLoader loader = nameToLoader.get(name);
Module m;
if (loader == null && name.equals("java.base")) {
// java.base is already defined to the VM
m = Object.class.getModule();
} else {
URI uri = mref.location().orElse(null);
m = new Module(layer, loader, descriptor, uri);
}
nameToModule.put(name, m);
}
// setup readability and exports/opens
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
ModuleDescriptor descriptor = mref.descriptor();
String mn = descriptor.name();
Module m = nameToModule.get(mn);
assert m != null;
// reads
Set<Module> reads = new HashSet<>();
// name -> source Module when in parent layer
Map<String, Module> nameToSource = Collections.emptyMap();
for (ResolvedModule other : resolvedModule.reads()) {
Module m2 = null;
if (other.configuration() == cf) {
// this configuration
m2 = nameToModule.get(other.name());
assert m2 != null;
} else {
// parent layer
for (ModuleLayer parent : layer.parents()) {
m2 = findModule(parent, other);
if (m2 != null)
break;
}
assert m2 != null;
if (nameToSource.isEmpty())
nameToSource = new HashMap<>();
nameToSource.put(other.name(), m2);
}
reads.add(m2);
// update VM view
addReads0(m, m2);
}
m.reads = reads;
// automatic modules read all unnamed modules
if (descriptor.isAutomatic()) {
m.implAddReads(ALL_UNNAMED_MODULE, true);
}
// exports and opens, skipped for open and automatic
if (!descriptor.isOpen() && !descriptor.isAutomatic()) {
if (isBootLayer && descriptor.opens().isEmpty()) {
// no open packages, no qualified exports to modules in parent layers
initExports(m, nameToModule);
} else {
initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
}
}
}
// then register the modules in the class loader's services catalog
if (hasPlatformModules) {
ClassLoader pcl = ClassLoaders.platformClassLoader();
ServicesCatalog bootCatalog = BootLoader.getServicesCatalog();
ServicesCatalog pclCatalog = ServicesCatalog.getServicesCatalog(pcl);
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
ModuleDescriptor descriptor = mref.descriptor();
if (!descriptor.provides().isEmpty()) {
String name = descriptor.name();
Module m = nameToModule.get(name);
ClassLoader loader = nameToLoader.get(name);
if (loader == null) {
bootCatalog.register(m);
} else if (loader == pcl) {
pclCatalog.register(m);
}
}
}
}
// record that there is a layer with modules defined to the class loader
for (ClassLoader loader : loaders) {
layer.bindToLoader(loader);
}
return nameToModule;
}
use of jdk.internal.module.ServicesCatalog in project Bytecoder by mirkosertic.
the class ModuleLayer method getServicesCatalog.
/**
* Returns the ServicesCatalog for this Layer, creating it if not
* already created.
*/
ServicesCatalog getServicesCatalog() {
ServicesCatalog servicesCatalog = this.servicesCatalog;
if (servicesCatalog != null)
return servicesCatalog;
synchronized (this) {
servicesCatalog = this.servicesCatalog;
if (servicesCatalog == null) {
servicesCatalog = ServicesCatalog.create();
nameToModule.values().forEach(servicesCatalog::register);
this.servicesCatalog = servicesCatalog;
}
}
return servicesCatalog;
}
Aggregations