Search in sources :

Example 6 with ModuleDescriptor

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

the class ModulePath method deriveModuleDescriptor.

/**
 * Treat the given JAR file as a module as follows:
 *
 * 1. The value of the Automatic-Module-Name attribute is the module name
 * 2. The version, and the module name when the  Automatic-Module-Name
 *    attribute is not present, is derived from the file ame of the JAR file
 * 3. All packages are derived from the .class files in the JAR file
 * 4. The contents of any META-INF/services configuration files are mapped
 *    to "provides" declarations
 * 5. The Main-Class attribute in the main attributes of the JAR manifest
 *    is mapped to the module descriptor mainClass if possible
 */
private ModuleDescriptor deriveModuleDescriptor(JarFile jf) throws IOException {
    // Read Automatic-Module-Name attribute if present
    Manifest man = jf.getManifest();
    Attributes attrs = null;
    String moduleName = null;
    if (man != null) {
        attrs = man.getMainAttributes();
        if (attrs != null) {
            moduleName = attrs.getValue(AUTOMATIC_MODULE_NAME);
        }
    }
    // Derive the version, and the module name if needed, from JAR file name
    String fn = jf.getName();
    int i = fn.lastIndexOf(File.separator);
    if (i != -1)
        fn = fn.substring(i + 1);
    // drop ".jar"
    String name = fn.substring(0, fn.length() - 4);
    String vs = null;
    // find first occurrence of -${NUMBER}. or -${NUMBER}$
    Matcher matcher = Patterns.DASH_VERSION.matcher(name);
    if (matcher.find()) {
        int start = matcher.start();
        // attempt to parse the tail as a version string
        try {
            String tail = name.substring(start + 1);
            ModuleDescriptor.Version.parse(tail);
            vs = tail;
        } catch (IllegalArgumentException ignore) {
        }
        name = name.substring(0, start);
    }
    // Create builder, using the name derived from file name when
    // Automatic-Module-Name not present
    Builder builder;
    if (moduleName != null) {
        try {
            builder = ModuleDescriptor.newAutomaticModule(moduleName);
        } catch (IllegalArgumentException e) {
            throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
        }
    } else {
        builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
    }
    // module version if present
    if (vs != null)
        builder.version(vs);
    // scan the names of the entries in the JAR file
    Map<Boolean, Set<String>> map = VersionedStream.stream(jf).filter(e -> !e.isDirectory()).map(JarEntry::getName).filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX))).collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX), Collectors.toSet()));
    Set<String> classFiles = map.get(Boolean.FALSE);
    Set<String> configFiles = map.get(Boolean.TRUE);
    // the packages containing class files
    Set<String> packages = classFiles.stream().map(this::toPackageName).flatMap(Optional::stream).distinct().collect(Collectors.toSet());
    // all packages are exported and open
    builder.packages(packages);
    // map names of service configuration files to service names
    Set<String> serviceNames = configFiles.stream().map(this::toServiceName).flatMap(Optional::stream).collect(Collectors.toSet());
    // parse each service configuration file
    for (String sn : serviceNames) {
        JarEntry entry = jf.getJarEntry(SERVICES_PREFIX + sn);
        List<String> providerClasses = new ArrayList<>();
        try (InputStream in = jf.getInputStream(entry)) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            String cn;
            while ((cn = nextLine(reader)) != null) {
                if (cn.length() > 0) {
                    String pn = packageName(cn);
                    if (!packages.contains(pn)) {
                        String msg = "Provider class " + cn + " not in module";
                        throw new InvalidModuleDescriptorException(msg);
                    }
                    providerClasses.add(cn);
                }
            }
        }
        if (!providerClasses.isEmpty())
            builder.provides(sn, providerClasses);
    }
    // Main-Class attribute if it exists
    if (attrs != null) {
        String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
        if (mainClass != null) {
            mainClass = mainClass.replace("/", ".");
            if (Checks.isClassName(mainClass)) {
                String pn = packageName(mainClass);
                if (packages.contains(pn)) {
                    builder.mainClass(mainClass);
                }
            }
        }
    }
    return builder.build();
}
Also used : Builder(java.lang.module.ModuleDescriptor.Builder) Manifest(java.util.jar.Manifest) NoSuchFileException(java.nio.file.NoSuchFileException) BufferedInputStream(java.io.BufferedInputStream) VersionedStream(jdk.internal.util.jar.VersionedStream) ModuleDescriptor(java.lang.module.ModuleDescriptor) ModuleReference(java.lang.module.ModuleReference) HashMap(java.util.HashMap) JarFile(java.util.jar.JarFile) ArrayList(java.util.ArrayList) Section(jdk.internal.jmod.JmodFile.Section) DirectoryStream(java.nio.file.DirectoryStream) JarEntry(java.util.jar.JarEntry) Matcher(java.util.regex.Matcher) ModuleFinder(java.lang.module.ModuleFinder) Map(java.util.Map) ZipFile(java.util.zip.ZipFile) URI(java.net.URI) Path(java.nio.file.Path) FindException(java.lang.module.FindException) PerfCounter(jdk.internal.perf.PerfCounter) ZipException(java.util.zip.ZipException) Files(java.nio.file.Files) Set(java.util.Set) IOException(java.io.IOException) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) InputStreamReader(java.io.InputStreamReader) Attributes(java.util.jar.Attributes) Collectors(java.util.stream.Collectors) File(java.io.File) UncheckedIOException(java.io.UncheckedIOException) Objects(java.util.Objects) List(java.util.List) JmodFile(jdk.internal.jmod.JmodFile) Paths(java.nio.file.Paths) InvalidModuleDescriptorException(java.lang.module.InvalidModuleDescriptorException) Optional(java.util.Optional) BufferedReader(java.io.BufferedReader) Pattern(java.util.regex.Pattern) Collections(java.util.Collections) InputStream(java.io.InputStream) Set(java.util.Set) Optional(java.util.Optional) InputStreamReader(java.io.InputStreamReader) Matcher(java.util.regex.Matcher) BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) Builder(java.lang.module.ModuleDescriptor.Builder) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) Attributes(java.util.jar.Attributes) ArrayList(java.util.ArrayList) Manifest(java.util.jar.Manifest) JarEntry(java.util.jar.JarEntry) InvalidModuleDescriptorException(java.lang.module.InvalidModuleDescriptorException) FindException(java.lang.module.FindException) BufferedReader(java.io.BufferedReader)

Example 7 with ModuleDescriptor

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

the class ModulePath method readJar.

/**
 * Returns a {@code ModuleReference} to a module in modular JAR file on
 * the file system.
 *
 * @throws IOException
 * @throws FindException
 * @throws InvalidModuleDescriptorException
 */
private ModuleReference readJar(Path file) throws IOException {
    try (JarFile jf = new JarFile(file.toFile(), // verify
    true, ZipFile.OPEN_READ, releaseVersion)) {
        ModuleInfo.Attributes attrs;
        JarEntry entry = jf.getJarEntry(MODULE_INFO);
        if (entry == null) {
            // no module-info.class so treat it as automatic module
            try {
                ModuleDescriptor md = deriveModuleDescriptor(jf);
                attrs = new ModuleInfo.Attributes(md, null, null, null);
            } catch (RuntimeException e) {
                throw new FindException("Unable to derive module descriptor for " + jf.getName(), e);
            }
        } else {
            attrs = ModuleInfo.read(jf.getInputStream(entry), () -> jarPackages(jf));
        }
        return ModuleReferences.newJarModule(attrs, patcher, file);
    } catch (ZipException e) {
        throw new FindException("Error reading " + file, e);
    }
}
Also used : ModuleDescriptor(java.lang.module.ModuleDescriptor) FindException(java.lang.module.FindException) ZipException(java.util.zip.ZipException) JarFile(java.util.jar.JarFile) JarEntry(java.util.jar.JarEntry)

Example 8 with ModuleDescriptor

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

the class ModuleBootstrap method boot.

/**
 * Initialize the module system, returning the boot layer.
 *
 * @see java.lang.System#initPhase2()
 */
public static ModuleLayer boot() throws Exception {
    // Step 0: Command line options
    long t0 = System.nanoTime();
    ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
    ModuleFinder appModulePath = finderFor("jdk.module.path");
    boolean isPatched = patcher.hasPatches();
    String mainModule = System.getProperty("jdk.module.main");
    Set<String> addModules = addModules();
    Set<String> limitModules = limitModules();
    PrintStream traceOutput = null;
    String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
    if (trace != null && Boolean.parseBoolean(trace))
        traceOutput = System.out;
    // Step 1: The observable system modules, either all system modules
    // or the system modules pre-generated for the initial module (the
    // initial module may be the unnamed module). If the system modules
    // are pre-generated for the initial module then resolution can be
    // skipped.
    long t1 = System.nanoTime();
    SystemModules systemModules = null;
    ModuleFinder systemModuleFinder;
    boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
    boolean needResolution = true;
    if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
        systemModules = SystemModuleFinders.systemModules(mainModule);
        if (systemModules != null && !isPatched && (traceOutput == null)) {
            needResolution = false;
        }
    }
    if (systemModules == null) {
        // all system modules are observable
        systemModules = SystemModuleFinders.allSystemModules();
    }
    if (systemModules != null) {
        // images build
        systemModuleFinder = SystemModuleFinders.of(systemModules);
    } else {
        // exploded build or testing
        systemModules = new ExplodedSystemModules();
        systemModuleFinder = SystemModuleFinders.ofSystem();
    }
    Counters.add("jdk.module.boot.1.systemModulesTime", t1);
    // Step 2: Define and load java.base. This patches all classes loaded
    // to date so that they are members of java.base. Once java.base is
    // loaded then resources in java.base are available for error messages
    // needed from here on.
    long t2 = System.nanoTime();
    ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
    if (base == null)
        throw new InternalError(JAVA_BASE + " not found");
    URI baseUri = base.location().orElse(null);
    if (baseUri == null)
        throw new InternalError(JAVA_BASE + " does not have a location");
    BootLoader.loadModule(base);
    Modules.defineModule(null, base.descriptor(), baseUri);
    Counters.add("jdk.module.boot.2.defineBaseTime", t2);
    if (getAndRemoveProperty("jdk.module.validation") != null) {
        return createBootLayerForValidation();
    }
    // Step 3: If resolution is needed then create the module finder and
    // the set of root modules to resolve.
    long t3 = System.nanoTime();
    ModuleFinder savedModuleFinder = null;
    ModuleFinder finder;
    Set<String> roots;
    if (needResolution) {
        // upgraded modules override the modules in the run-time image
        if (upgradeModulePath != null)
            systemModuleFinder = ModuleFinder.compose(upgradeModulePath, systemModuleFinder);
        // The module finder: [--upgrade-module-path] system [--module-path]
        if (appModulePath != null) {
            finder = ModuleFinder.compose(systemModuleFinder, appModulePath);
        } else {
            finder = systemModuleFinder;
        }
        // The root modules to resolve
        roots = new HashSet<>();
        // launcher -m option to specify the main/initial module
        if (mainModule != null)
            roots.add(mainModule);
        // additional module(s) specified by --add-modules
        boolean addAllDefaultModules = false;
        boolean addAllSystemModules = false;
        boolean addAllApplicationModules = false;
        for (String mod : addModules) {
            switch(mod) {
                case ALL_DEFAULT:
                    addAllDefaultModules = true;
                    break;
                case ALL_SYSTEM:
                    addAllSystemModules = true;
                    break;
                case ALL_MODULE_PATH:
                    addAllApplicationModules = true;
                    break;
                default:
                    roots.add(mod);
            }
        }
        // --limit-modules
        savedModuleFinder = finder;
        if (!limitModules.isEmpty()) {
            finder = limitFinder(finder, limitModules, roots);
        }
        // the default set of roots.
        if (mainModule == null || addAllDefaultModules) {
            roots.addAll(DefaultRoots.compute(systemModuleFinder, finder));
        }
        // modules will be resolved.
        if (addAllSystemModules) {
            // observable modules
            ModuleFinder f = finder;
            systemModuleFinder.findAll().stream().map(ModuleReference::descriptor).map(ModuleDescriptor::name).filter(// observable
            mn -> f.find(mn).isPresent()).forEach(mn -> roots.add(mn));
        }
        // modules on the application module path will be resolved.
        if (appModulePath != null && addAllApplicationModules) {
            // observable modules
            ModuleFinder f = finder;
            appModulePath.findAll().stream().map(ModuleReference::descriptor).map(ModuleDescriptor::name).filter(// observable
            mn -> f.find(mn).isPresent()).forEach(mn -> roots.add(mn));
        }
    } else {
        // no resolution case
        finder = systemModuleFinder;
        roots = null;
    }
    Counters.add("jdk.module.boot.3.optionsAndRootsTime", t3);
    // Step 4: Resolve the root modules, with service binding, to create
    // the configuration for the boot layer. If resolution is not needed
    // then create the configuration for the boot layer from the
    // readability graph created at link time.
    long t4 = System.nanoTime();
    Configuration cf;
    if (needResolution) {
        cf = JLMA.resolveAndBind(finder, roots, traceOutput);
    } else {
        Map<String, Set<String>> map = systemModules.moduleReads();
        cf = JLMA.newConfiguration(systemModuleFinder, map);
    }
    // check that modules specified to --patch-module are resolved
    if (isPatched) {
        patcher.patchedModules().stream().filter(mn -> !cf.findModule(mn).isPresent()).forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
    }
    Counters.add("jdk.module.boot.4.resolveTime", t4);
    // Step 5: Map the modules in the configuration to class loaders.
    // The static configuration provides the mapping of standard and JDK
    // modules to the boot and platform loaders. All other modules (JDK
    // tool modules, and both explicit and automatic modules on the
    // application module path) are defined to the application class
    // loader.
    long t5 = System.nanoTime();
    // mapping of modules to class loaders
    Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
    // loaded from the runtime image
    if (haveModulePath) {
        for (ResolvedModule resolvedModule : cf.modules()) {
            ModuleReference mref = resolvedModule.reference();
            String name = mref.descriptor().name();
            ClassLoader cl = clf.apply(name);
            if (cl == null) {
                if (upgradeModulePath != null && upgradeModulePath.find(name).isPresent())
                    fail(name + ": cannot be loaded from upgrade module path");
                if (!systemModuleFinder.find(name).isPresent())
                    fail(name + ": cannot be loaded from application module path");
            }
        }
    }
    // check for split packages in the modules mapped to the built-in loaders
    if (systemModules.hasSplitPackages() || isPatched || haveModulePath) {
        checkSplitPackages(cf, clf);
    }
    // load/register the modules with the built-in class loaders
    loadModules(cf, clf);
    Counters.add("jdk.module.boot.5.loadModulesTime", t5);
    // Step 6: Define all modules to the VM
    long t6 = System.nanoTime();
    ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
    Counters.add("jdk.module.boot.6.layerCreateTime", t6);
    // check incubating status
    if (systemModules.hasIncubatorModules() || haveModulePath) {
        checkIncubatingStatus(cf);
    }
    // --add-reads, --add-exports/--add-opens, and --illegal-access
    long t7 = System.nanoTime();
    addExtraReads(bootLayer);
    boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
    addIllegalAccess(upgradeModulePath, systemModules, bootLayer, extraExportsOrOpens);
    Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
    // save module finders for later use
    if (savedModuleFinder != null) {
        unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
        if (savedModuleFinder != finder)
            limitedFinder = new SafeModuleFinder(finder);
    }
    // total time to initialize
    Counters.add("jdk.module.boot.totalTime", t0);
    Counters.publish();
    return bootLayer;
}
Also used : ModuleDescriptor(java.lang.module.ModuleDescriptor) ModuleReference(java.lang.module.ModuleReference) HashMap(java.util.HashMap) JavaLangModuleAccess(jdk.internal.misc.JavaLangModuleAccess) Function(java.util.function.Function) JavaLangAccess(jdk.internal.misc.JavaLangAccess) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ResolvedModule(java.lang.module.ResolvedModule) ModuleFinder(java.lang.module.ModuleFinder) Map(java.util.Map) URI(java.net.URI) NoSuchElementException(java.util.NoSuchElementException) Path(java.nio.file.Path) PrintStream(java.io.PrintStream) PerfCounter(jdk.internal.perf.PerfCounter) Iterator(java.util.Iterator) SharedSecrets(jdk.internal.misc.SharedSecrets) Set(java.util.Set) Configuration(java.lang.module.Configuration) Collectors(java.util.stream.Collectors) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) File(java.io.File) Objects(java.util.Objects) BootLoader(jdk.internal.loader.BootLoader) List(java.util.List) Paths(java.nio.file.Paths) Optional(java.util.Optional) Collections(java.util.Collections) PrintStream(java.io.PrintStream) ModuleFinder(java.lang.module.ModuleFinder) HashSet(java.util.HashSet) Set(java.util.Set) Configuration(java.lang.module.Configuration) URI(java.net.URI) ModuleDescriptor(java.lang.module.ModuleDescriptor) ResolvedModule(java.lang.module.ResolvedModule) ModuleReference(java.lang.module.ModuleReference) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader)

Example 9 with ModuleDescriptor

use of java.lang.module.ModuleDescriptor in project jboss-modules by jboss-modules.

the class JDKModuleFinder method findModule.

public ModuleSpec findModule(final String name, final ModuleLoader delegateLoader) {
    final Set<String> packages;
    final Module module;
    if ("org.jboss.modules".equals(name)) {
        module = getClass().getModule();
        if (module.isNamed()) {
            packages = module.getPackages();
        } else {
            packages = Set.of("org.jboss.modules", "org.jboss.modules.filter", "org.jboss.modules.log", "org.jboss.modules.management", "org.jboss.modules.maven", "org.jboss.modules.ref", "org.jboss.modules.security", "org.jboss.modules.xml");
        }
    } else {
        final Optional<Module> moduleOptional = layer.findModule(name);
        if (!moduleOptional.isPresent()) {
            return null;
        }
        module = moduleOptional.get();
        packages = module.getPackages();
    }
    final ModuleSpec.Builder builder = ModuleSpec.build(name);
    final ModuleDescriptor descriptor = module.getDescriptor();
    if (descriptor != null) {
        final Optional<String> version = descriptor.rawVersion();
        if (version.isPresent())
            builder.setVersion(Version.parse(version.get()));
        for (ModuleDescriptor.Requires require : descriptor.requires()) {
            final Set<ModuleDescriptor.Requires.Modifier> modifiers = require.modifiers();
            builder.addDependency(new ModuleDependencySpecBuilder().setName(require.name()).setExport(modifiers.contains(ModuleDescriptor.Requires.Modifier.TRANSITIVE)).setOptional(modifiers.contains(ModuleDescriptor.Requires.Modifier.STATIC)).build());
        }
    }
    final Set<String> paths = new HashSet<>(packages.size());
    for (String pkg : packages) {
        paths.add(pkg.replace('.', '/'));
    }
    final LocalDependencySpecBuilder depBuilder = new LocalDependencySpecBuilder();
    depBuilder.setLoaderPaths(paths);
    depBuilder.setExport(true);
    depBuilder.setLocalLoader(new JDKModuleLoader(module, packages));
    builder.addDependency(depBuilder.build());
    return builder.create();
}
Also used : ModuleDescriptor(java.lang.module.ModuleDescriptor) Module(java.lang.Module) HashSet(java.util.HashSet)

Example 10 with ModuleDescriptor

use of java.lang.module.ModuleDescriptor in project openj9 by eclipse.

the class MyLoader method dumpModules.

private void dumpModules() {
    HashSet<Option> opts = new HashSet<>(Arrays.asList(new Option[] { Option.RETAIN_CLASS_REFERENCE, Option.SHOW_HIDDEN_FRAMES, Option.SHOW_REFLECT_FRAMES }));
    List<StackFrame> frameList = (StackWalker.getInstance(opts)).walk(s -> s.collect(Collectors.toList()));
    for (StackFrame f : frameList) {
        Module frameModule = f.getDeclaringClass().getModule();
        if ((null != frameModule)) {
            ModuleDescriptor d = frameModule.getDescriptor();
            if (null != d) {
                StackTraceElement e = f.toStackTraceElement();
                String modName = d.name();
                if (null != modName) {
                    assertEquals(modName, e.getModuleName(), "Wrong module name");
                }
                Optional<Version> modVersion = d.version();
                if (modVersion.isPresent()) {
                    assertEquals(modVersion.get(), e.getModuleVersion(), "Wrong module version");
                }
                if (f.getDeclaringClass() == Thread.class) {
                    assertEquals("java.base", e.getModuleName(), "Wrong module name");
                }
            }
        }
    }
}
Also used : ModuleDescriptor(java.lang.module.ModuleDescriptor) Version(java.lang.module.ModuleDescriptor.Version) StackFrame(java.lang.StackWalker.StackFrame) Option(java.lang.StackWalker.Option) Module(java.lang.Module) HashSet(java.util.HashSet)

Aggregations

ModuleDescriptor (java.lang.module.ModuleDescriptor)19 HashMap (java.util.HashMap)12 HashSet (java.util.HashSet)11 ModuleReference (java.lang.module.ModuleReference)10 ResolvedModule (java.lang.module.ResolvedModule)9 Set (java.util.Set)9 Map (java.util.Map)8 URI (java.net.URI)7 ArrayList (java.util.ArrayList)7 File (java.io.File)6 IOException (java.io.IOException)6 Collections (java.util.Collections)6 List (java.util.List)6 Optional (java.util.Optional)6 UncheckedIOException (java.io.UncheckedIOException)5 ModuleFinder (java.lang.module.ModuleFinder)5 Path (java.nio.file.Path)5 Paths (java.nio.file.Paths)5 JarFile (java.util.jar.JarFile)5 Collectors (java.util.stream.Collectors)5