Search in sources :

Example 1 with Provides

use of java.lang.module.ModuleDescriptor.Provides in project Bytecoder by mirkosertic.

the class Resolver method bind.

/**
 * Augments the set of resolved modules with modules induced by the
 * service-use relation.
 */
Resolver bind() {
    // Scan the finders for all available service provider modules. As
    // java.base uses services then then module finders will be scanned
    // anyway.
    Map<String, Set<ModuleReference>> availableProviders = new HashMap<>();
    for (ModuleReference mref : findAll()) {
        ModuleDescriptor descriptor = mref.descriptor();
        if (!descriptor.provides().isEmpty()) {
            for (Provides provides : descriptor.provides()) {
                String sn = provides.service();
                // computeIfAbsent
                Set<ModuleReference> providers = availableProviders.get(sn);
                if (providers == null) {
                    providers = new HashSet<>();
                    availableProviders.put(sn, providers);
                }
                providers.add(mref);
            }
        }
    }
    // create the visit stack
    Deque<ModuleDescriptor> q = new ArrayDeque<>();
    // the initial set of modules that may use services
    Set<ModuleDescriptor> initialConsumers;
    if (ModuleLayer.boot() == null) {
        initialConsumers = new HashSet<>();
    } else {
        initialConsumers = parents.stream().flatMap(Configuration::configurations).distinct().flatMap(c -> c.descriptors().stream()).collect(Collectors.toSet());
    }
    for (ModuleReference mref : nameToReference.values()) {
        initialConsumers.add(mref.descriptor());
    }
    // Where there is a consumer of a service then resolve all modules
    // that provide an implementation of that service
    Set<ModuleDescriptor> candidateConsumers = initialConsumers;
    do {
        for (ModuleDescriptor descriptor : candidateConsumers) {
            if (!descriptor.uses().isEmpty()) {
                // the modules that provide at least one service
                Set<ModuleDescriptor> modulesToBind = null;
                if (isTracing()) {
                    modulesToBind = new HashSet<>();
                }
                for (String service : descriptor.uses()) {
                    Set<ModuleReference> mrefs = availableProviders.get(service);
                    if (mrefs != null) {
                        for (ModuleReference mref : mrefs) {
                            ModuleDescriptor provider = mref.descriptor();
                            if (!provider.equals(descriptor)) {
                                if (isTracing() && modulesToBind.add(provider)) {
                                    trace("%s binds %s", descriptor.name(), nameAndInfo(mref));
                                }
                                String pn = provider.name();
                                if (!nameToReference.containsKey(pn)) {
                                    addFoundModule(mref);
                                    q.push(provider);
                                }
                            }
                        }
                    }
                }
            }
        }
        candidateConsumers = resolve(q);
    } while (!candidateConsumers.isEmpty());
    return this;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) Provides(java.lang.module.ModuleDescriptor.Provides) ArrayDeque(java.util.ArrayDeque)

Example 2 with Provides

use of java.lang.module.ModuleDescriptor.Provides in project Bytecoder by mirkosertic.

the class LauncherHelper method describeModule.

/**
 * Called by the launcher to describe a module
 */
static void describeModule(String moduleName) {
    initOutput(System.out);
    ModuleFinder finder = ModuleBootstrap.limitedFinder();
    ModuleReference mref = finder.find(moduleName).orElse(null);
    if (mref == null) {
        abort(null, "java.launcher.module.error4", moduleName);
    }
    ModuleDescriptor md = mref.descriptor();
    // one-line summary
    showModule(mref);
    // unqualified exports (sorted by package)
    md.exports().stream().filter(e -> !e.isQualified()).sorted(Comparator.comparing(Exports::source)).map(e -> Stream.concat(Stream.of(e.source()), toStringStream(e.modifiers())).collect(Collectors.joining(" "))).forEach(sourceAndMods -> ostream.format("exports %s%n", sourceAndMods));
    // dependences
    for (Requires r : md.requires()) {
        String nameAndMods = Stream.concat(Stream.of(r.name()), toStringStream(r.modifiers())).collect(Collectors.joining(" "));
        ostream.format("requires %s", nameAndMods);
        finder.find(r.name()).map(ModuleReference::descriptor).filter(ModuleDescriptor::isAutomatic).ifPresent(any -> ostream.print(" automatic"));
        ostream.println();
    }
    // service use and provides
    for (String s : md.uses()) {
        ostream.format("uses %s%n", s);
    }
    for (Provides ps : md.provides()) {
        String names = ps.providers().stream().collect(Collectors.joining(" "));
        ostream.format("provides %s with %s%n", ps.service(), names);
    }
    // qualified exports
    for (Exports e : md.exports()) {
        if (e.isQualified()) {
            String who = e.targets().stream().collect(Collectors.joining(" "));
            ostream.format("qualified exports %s to %s%n", e.source(), who);
        }
    }
    // open packages
    for (Opens opens : md.opens()) {
        if (opens.isQualified())
            ostream.print("qualified ");
        String sourceAndMods = Stream.concat(Stream.of(opens.source()), toStringStream(opens.modifiers())).collect(Collectors.joining(" "));
        ostream.format("opens %s", sourceAndMods);
        if (opens.isQualified()) {
            String who = opens.targets().stream().collect(Collectors.joining(" "));
            ostream.format(" to %s", who);
        }
        ostream.println();
    }
    // non-exported/non-open packages
    Set<String> concealed = new TreeSet<>(md.packages());
    md.exports().stream().map(Exports::source).forEach(concealed::remove);
    md.opens().stream().map(Opens::source).forEach(concealed::remove);
    concealed.forEach(p -> ostream.format("contains %s%n", p));
}
Also used : Manifest(java.util.jar.Manifest) NoSuchFileException(java.nio.file.NoSuchFileException) ModuleReference(java.lang.module.ModuleReference) JarFile(java.util.jar.JarFile) Requires(java.lang.module.ModuleDescriptor.Requires) BigDecimal(java.math.BigDecimal) DirectoryStream(java.nio.file.DirectoryStream) Category(java.util.Locale.Category) ModuleFinder(java.lang.module.ModuleFinder) Locale(java.util.Locale) Map(java.util.Map) URI(java.net.URI) Method(java.lang.reflect.Method) Path(java.nio.file.Path) FindException(java.lang.module.FindException) RoundingMode(java.math.RoundingMode) Set(java.util.Set) Configuration(java.lang.module.Configuration) Attributes(java.util.jar.Attributes) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) Exports(java.lang.module.ModuleDescriptor.Exports) List(java.util.List) Stream(java.util.stream.Stream) Modifier(java.lang.reflect.Modifier) Optional(java.util.Optional) VM(jdk.internal.misc.VM) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Provides(java.lang.module.ModuleDescriptor.Provides) ModuleDescriptor(java.lang.module.ModuleDescriptor) HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) MessageFormat(java.text.MessageFormat) ArrayList(java.util.ArrayList) ResolvedModule(java.lang.module.ResolvedModule) Charset(java.nio.charset.Charset) ResourceBundle(java.util.ResourceBundle) PrintStream(java.io.PrintStream) Properties(java.util.Properties) Iterator(java.util.Iterator) Files(java.nio.file.Files) Opens(java.lang.module.ModuleDescriptor.Opens) IOException(java.io.IOException) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) File(java.io.File) Normalizer(java.text.Normalizer) ModuleBootstrap(jdk.internal.module.ModuleBootstrap) Paths(java.nio.file.Paths) Modules(jdk.internal.module.Modules) Comparator(java.util.Comparator) Collections(java.util.Collections) ModuleDescriptor(java.lang.module.ModuleDescriptor) ModuleFinder(java.lang.module.ModuleFinder) Opens(java.lang.module.ModuleDescriptor.Opens) ModuleReference(java.lang.module.ModuleReference) Requires(java.lang.module.ModuleDescriptor.Requires) TreeSet(java.util.TreeSet) Provides(java.lang.module.ModuleDescriptor.Provides) Exports(java.lang.module.ModuleDescriptor.Exports)

Example 3 with Provides

use of java.lang.module.ModuleDescriptor.Provides in project Bytecoder by mirkosertic.

the class Resolver method checkExportSuppliers.

/**
 * Checks the readability graph to ensure that
 * <ol>
 *   <li><p> A module does not read two or more modules with the same name.
 *   This includes the case where a module reads another another with the
 *   same name as itself. </p></li>
 *   <li><p> Two or more modules in the configuration don't export the same
 *   package to a module that reads both. This includes the case where a
 *   module {@code M} containing package {@code p} reads another module
 *   that exports {@code p} to {@code M}. </p></li>
 *   <li><p> A module {@code M} doesn't declare that it "{@code uses p.S}"
 *   or "{@code provides p.S with ...}" but package {@code p} is neither
 *   in module {@code M} nor exported to {@code M} by any module that
 *   {@code M} reads. </p></li>
 * </ol>
 */
private void checkExportSuppliers(Map<ResolvedModule, Set<ResolvedModule>> graph) {
    for (Map.Entry<ResolvedModule, Set<ResolvedModule>> e : graph.entrySet()) {
        ModuleDescriptor descriptor1 = e.getKey().descriptor();
        String name1 = descriptor1.name();
        // the names of the modules that are read (including self)
        Set<String> names = new HashSet<>();
        names.add(name1);
        // the map of packages that are local or exported to descriptor1
        Map<String, ModuleDescriptor> packageToExporter = new HashMap<>();
        // local packages
        Set<String> packages = descriptor1.packages();
        for (String pn : packages) {
            packageToExporter.put(pn, descriptor1);
        }
        // descriptor1 reads descriptor2
        Set<ResolvedModule> reads = e.getValue();
        for (ResolvedModule endpoint : reads) {
            ModuleDescriptor descriptor2 = endpoint.descriptor();
            String name2 = descriptor2.name();
            if (descriptor2 != descriptor1 && !names.add(name2)) {
                if (name2.equals(name1)) {
                    resolveFail("Module %s reads another module named %s", name1, name1);
                } else {
                    resolveFail("Module %s reads more than one module named %s", name1, name2);
                }
            }
            if (descriptor2.isAutomatic()) {
                // automatic modules read self and export all packages
                if (descriptor2 != descriptor1) {
                    for (String source : descriptor2.packages()) {
                        ModuleDescriptor supplier = packageToExporter.putIfAbsent(source, descriptor2);
                        // descriptor2 and 'supplier' export source to descriptor1
                        if (supplier != null) {
                            failTwoSuppliers(descriptor1, source, descriptor2, supplier);
                        }
                    }
                }
            } else {
                for (ModuleDescriptor.Exports export : descriptor2.exports()) {
                    if (export.isQualified()) {
                        if (!export.targets().contains(descriptor1.name()))
                            continue;
                    }
                    // source is exported by descriptor2
                    String source = export.source();
                    ModuleDescriptor supplier = packageToExporter.putIfAbsent(source, descriptor2);
                    // descriptor2 and 'supplier' export source to descriptor1
                    if (supplier != null) {
                        failTwoSuppliers(descriptor1, source, descriptor2, supplier);
                    }
                }
            }
        }
        // uses/provides checks not applicable to automatic modules
        if (!descriptor1.isAutomatic()) {
            // uses S
            for (String service : descriptor1.uses()) {
                String pn = packageName(service);
                if (!packageToExporter.containsKey(pn)) {
                    resolveFail("Module %s does not read a module that exports %s", descriptor1.name(), pn);
                }
            }
            // provides S
            for (ModuleDescriptor.Provides provides : descriptor1.provides()) {
                String pn = packageName(provides.service());
                if (!packageToExporter.containsKey(pn)) {
                    resolveFail("Module %s does not read a module that exports %s", descriptor1.name(), pn);
                }
            }
        }
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) Provides(java.lang.module.ModuleDescriptor.Provides) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 4 with Provides

use of java.lang.module.ModuleDescriptor.Provides in project Bytecoder by mirkosertic.

the class ServicesCatalog method register.

/**
 * Registers the providers in the given module in this services catalog.
 */
public void register(Module module) {
    ModuleDescriptor descriptor = module.getDescriptor();
    for (Provides provides : descriptor.provides()) {
        String service = provides.service();
        List<String> providerNames = provides.providers();
        int count = providerNames.size();
        if (count == 1) {
            String pn = providerNames.get(0);
            providers(service).add(new ServiceProvider(module, pn));
        } else {
            List<ServiceProvider> list = new ArrayList<>(count);
            for (String pn : providerNames) {
                list.add(new ServiceProvider(module, pn));
            }
            providers(service).addAll(list);
        }
    }
}
Also used : ModuleDescriptor(java.lang.module.ModuleDescriptor) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Provides(java.lang.module.ModuleDescriptor.Provides)

Aggregations

Provides (java.lang.module.ModuleDescriptor.Provides)4 HashMap (java.util.HashMap)3 Set (java.util.Set)3 ModuleDescriptor (java.lang.module.ModuleDescriptor)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 LinkedHashSet (java.util.LinkedHashSet)2 Map (java.util.Map)2 File (java.io.File)1 IOException (java.io.IOException)1 PrintStream (java.io.PrintStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 Configuration (java.lang.module.Configuration)1 FindException (java.lang.module.FindException)1 Exports (java.lang.module.ModuleDescriptor.Exports)1 Opens (java.lang.module.ModuleDescriptor.Opens)1 Requires (java.lang.module.ModuleDescriptor.Requires)1 ModuleFinder (java.lang.module.ModuleFinder)1 ModuleReference (java.lang.module.ModuleReference)1 ResolvedModule (java.lang.module.ResolvedModule)1