Search in sources :

Example 1 with ServicesCatalog

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;
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ServicesCatalog(jdk.internal.module.ServicesCatalog) URI(java.net.URI) ModuleDescriptor(java.lang.module.ModuleDescriptor) ResolvedModule(java.lang.module.ResolvedModule) ModuleReference(java.lang.module.ModuleReference) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) ResolvedModule(java.lang.module.ResolvedModule) HashSet(java.util.HashSet)

Example 2 with ServicesCatalog

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;
}
Also used : ServicesCatalog(jdk.internal.module.ServicesCatalog)

Aggregations

ServicesCatalog (jdk.internal.module.ServicesCatalog)2 ModuleDescriptor (java.lang.module.ModuleDescriptor)1 ModuleReference (java.lang.module.ModuleReference)1 ResolvedModule (java.lang.module.ResolvedModule)1 URI (java.net.URI)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 BuiltinClassLoader (jdk.internal.loader.BuiltinClassLoader)1