Search in sources :

Example 1 with BuiltinClassLoader

use of jdk.internal.loader.BuiltinClassLoader in project Bytecoder by mirkosertic.

the class Class method getResourceAsStream.

/**
 * Finds a resource with a given name.
 *
 * <p> If this class is in a named {@link Module Module} then this method
 * will attempt to find the resource in the module. This is done by
 * delegating to the module's class loader {@link
 * ClassLoader#findResource(String,String) findResource(String,String)}
 * method, invoking it with the module name and the absolute name of the
 * resource. Resources in named modules are subject to the rules for
 * encapsulation specified in the {@code Module} {@link
 * Module#getResourceAsStream getResourceAsStream} method and so this
 * method returns {@code null} when the resource is a
 * non-"{@code .class}" resource in a package that is not open to the
 * caller's module.
 *
 * <p> Otherwise, if this class is not in a named module then the rules for
 * searching resources associated with a given class are implemented by the
 * defining {@linkplain ClassLoader class loader} of the class.  This method
 * delegates to this object's class loader.  If this object was loaded by
 * the bootstrap class loader, the method delegates to {@link
 * ClassLoader#getSystemResourceAsStream}.
 *
 * <p> Before delegation, an absolute resource name is constructed from the
 * given resource name using this algorithm:
 *
 * <ul>
 *
 * <li> If the {@code name} begins with a {@code '/'}
 * (<code>'&#92;u002f'</code>), then the absolute name of the resource is the
 * portion of the {@code name} following the {@code '/'}.
 *
 * <li> Otherwise, the absolute name is of the following form:
 *
 * <blockquote>
 *   {@code modified_package_name/name}
 * </blockquote>
 *
 * <p> Where the {@code modified_package_name} is the package name of this
 * object with {@code '/'} substituted for {@code '.'}
 * (<code>'&#92;u002e'</code>).
 *
 * </ul>
 *
 * @param  name name of the desired resource
 * @return  A {@link java.io.InputStream} object; {@code null} if no
 *          resource with this name is found, the resource is in a package
 *          that is not {@link Module#isOpen(String, Module) open} to at
 *          least the caller module, or access to the resource is denied
 *          by the security manager.
 * @throws  NullPointerException If {@code name} is {@code null}
 *
 * @see Module#getResourceAsStream(String)
 * @since  1.1
 * @revised 9
 * @spec JPMS
 */
@CallerSensitive
public InputStream getResourceAsStream(String name) {
    name = resolveName(name);
    Module thisModule = getModule();
    if (thisModule.isNamed()) {
        // check if resource can be located by caller
        if (Resources.canEncapsulate(name) && !isOpenToCaller(name, Reflection.getCallerClass())) {
            return null;
        }
        // resource not encapsulated or in package open to caller
        String mn = thisModule.getName();
        ClassLoader cl = getClassLoader0();
        try {
            // need for a URL connection
            if (cl == null) {
                return BootLoader.findResourceAsStream(mn, name);
            } else if (cl instanceof BuiltinClassLoader) {
                return ((BuiltinClassLoader) cl).findResourceAsStream(mn, name);
            } else {
                URL url = cl.findResource(mn, name);
                return (url != null) ? url.openStream() : null;
            }
        } catch (IOException | SecurityException e) {
            return null;
        }
    }
    // unnamed module
    ClassLoader cl = getClassLoader0();
    if (cl == null) {
        return ClassLoader.getSystemResourceAsStream(name);
    } else {
        return cl.getResourceAsStream(name);
    }
}
Also used : BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) IOException(java.io.IOException) URL(java.net.URL) CallerSensitive(jdk.internal.reflect.CallerSensitive)

Example 2 with BuiltinClassLoader

use of jdk.internal.loader.BuiltinClassLoader in project Bytecoder by mirkosertic.

the class Modules method loadModule.

/**
 * Called by the VM to load a system module, typically "java.instrument" or
 * "jdk.management.agent". If the module is not loaded then it is resolved
 * and loaded (along with any dependences that weren't previously loaded)
 * into a child layer.
 */
public static synchronized Module loadModule(String name) {
    ModuleLayer top = topLayer;
    if (top == null)
        top = ModuleLayer.boot();
    Module module = top.findModule(name).orElse(null);
    if (module != null) {
        // module already loaded
        return module;
    }
    // resolve the module with the top-most layer as the parent
    ModuleFinder empty = ModuleFinder.of();
    ModuleFinder finder = ModuleBootstrap.unlimitedFinder();
    Set<String> roots = Set.of(name);
    Configuration cf = top.configuration().resolveAndBind(empty, finder, roots);
    // create the child layer
    Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
    ModuleLayer newLayer = top.defineModules(cf, clf);
    // add qualified exports/opens to give access to modules in child layer
    Map<String, Module> map = newLayer.modules().stream().collect(Collectors.toMap(Module::getName, Function.identity()));
    ModuleLayer layer = top;
    while (layer != null) {
        for (Module m : layer.modules()) {
            // qualified exports
            m.getDescriptor().exports().stream().filter(ModuleDescriptor.Exports::isQualified).forEach(e -> e.targets().forEach(target -> {
                Module other = map.get(target);
                if (other != null) {
                    addExports(m, e.source(), other);
                }
            }));
            // qualified opens
            m.getDescriptor().opens().stream().filter(ModuleDescriptor.Opens::isQualified).forEach(o -> o.targets().forEach(target -> {
                Module other = map.get(target);
                if (other != null) {
                    addOpens(m, o.source(), other);
                }
            }));
        }
        List<ModuleLayer> parents = layer.parents();
        assert parents.size() <= 1;
        layer = parents.isEmpty() ? null : parents.get(0);
    }
    // update security manager before making types visible
    JLA.addNonExportedPackages(newLayer);
    // update the built-in class loaders to make the types visible
    for (ResolvedModule resolvedModule : cf.modules()) {
        ModuleReference mref = resolvedModule.reference();
        String mn = mref.descriptor().name();
        ClassLoader cl = clf.apply(mn);
        if (cl == null) {
            BootLoader.loadModule(mref);
        } else {
            ((BuiltinClassLoader) cl).loadModule(mref);
        }
    }
    // new top layer
    topLayer = newLayer;
    // return module
    return newLayer.findModule(name).orElseThrow(() -> new InternalError("module not loaded"));
}
Also used : SharedSecrets(jdk.internal.misc.SharedSecrets) ClassLoaders(jdk.internal.loader.ClassLoaders) ModuleDescriptor(java.lang.module.ModuleDescriptor) Set(java.util.Set) Configuration(java.lang.module.Configuration) ModuleReference(java.lang.module.ModuleReference) PrivilegedAction(java.security.PrivilegedAction) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) JavaLangAccess(jdk.internal.misc.JavaLangAccess) BootLoader(jdk.internal.loader.BootLoader) List(java.util.List) ResolvedModule(java.lang.module.ResolvedModule) ModuleFinder(java.lang.module.ModuleFinder) Map(java.util.Map) URI(java.net.URI) AccessController(java.security.AccessController) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) ModuleFinder(java.lang.module.ModuleFinder) Configuration(java.lang.module.Configuration) 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)

Example 3 with BuiltinClassLoader

use of jdk.internal.loader.BuiltinClassLoader in project Bytecoder by mirkosertic.

the class Module method getResourceAsStream.

// -- misc --
/**
 * Returns an input stream for reading a resource in this module.
 * The {@code name} parameter is a {@code '/'}-separated path name that
 * identifies the resource. As with {@link Class#getResourceAsStream
 * Class.getResourceAsStream}, this method delegates to the module's class
 * loader {@link ClassLoader#findResource(String,String)
 * findResource(String,String)} method, invoking it with the module name
 * (or {@code null} when the module is unnamed) and the name of the
 * resource. If the resource name has a leading slash then it is dropped
 * before delegation.
 *
 * <p> A resource in a named module may be <em>encapsulated</em> so that
 * it cannot be located by code in other modules. Whether a resource can be
 * located or not is determined as follows: </p>
 *
 * <ul>
 *     <li> If the resource name ends with  "{@code .class}" then it is not
 *     encapsulated. </li>
 *
 *     <li> A <em>package name</em> is derived from the resource name. If
 *     the package name is a {@linkplain #getPackages() package} in the
 *     module then the resource can only be located by the caller of this
 *     method when the package is {@linkplain #isOpen(String,Module) open}
 *     to at least the caller's module. If the resource is not in a
 *     package in the module then the resource is not encapsulated. </li>
 * </ul>
 *
 * <p> In the above, the <em>package name</em> for a resource is derived
 * from the subsequence of characters that precedes the last {@code '/'} in
 * the name and then replacing each {@code '/'} character in the subsequence
 * with {@code '.'}. A leading slash is ignored when deriving the package
 * name. As an example, the package name derived for a resource named
 * "{@code a/b/c/foo.properties}" is "{@code a.b.c}". A resource name
 * with the name "{@code META-INF/MANIFEST.MF}" is never encapsulated
 * because "{@code META-INF}" is not a legal package name. </p>
 *
 * <p> This method returns {@code null} if the resource is not in this
 * module, the resource is encapsulated and cannot be located by the caller,
 * or access to the resource is denied by the security manager. </p>
 *
 * @param  name
 *         The resource name
 *
 * @return An input stream for reading the resource or {@code null}
 *
 * @throws IOException
 *         If an I/O error occurs
 *
 * @see Class#getResourceAsStream(String)
 */
@CallerSensitive
public InputStream getResourceAsStream(String name) throws IOException {
    if (name.startsWith("/")) {
        name = name.substring(1);
    }
    if (isNamed() && Resources.canEncapsulate(name)) {
        Module caller = getCallerModule(Reflection.getCallerClass());
        if (caller != this && caller != Object.class.getModule()) {
            String pn = Resources.toPackageName(name);
            if (getPackages().contains(pn)) {
                if (caller == null && !isOpen(pn)) {
                    // no caller, package not open
                    return null;
                }
                if (!isOpen(pn, caller)) {
                    // package not open to caller
                    return null;
                }
            }
        }
    }
    String mn = this.name;
    // special-case built-in class loaders to avoid URL connection
    if (loader == null) {
        return BootLoader.findResourceAsStream(mn, name);
    } else if (loader instanceof BuiltinClassLoader) {
        return ((BuiltinClassLoader) loader).findResourceAsStream(mn, name);
    }
    // locate resource in module
    URL url = loader.findResource(mn, name);
    if (url != null) {
        try {
            return url.openStream();
        } catch (SecurityException e) {
        }
    }
    return null;
}
Also used : BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) ResolvedModule(java.lang.module.ResolvedModule) URL(java.net.URL) CallerSensitive(jdk.internal.reflect.CallerSensitive)

Example 4 with BuiltinClassLoader

use of jdk.internal.loader.BuiltinClassLoader in project Bytecoder by mirkosertic.

the class StackTraceElement method computeFormat.

/**
 * Called from of() methods to set the 'format' bitmap using the Class
 * reference stored in declaringClassObject, and then clear the reference.
 *
 * <p>
 * If the module is a non-upgradeable JDK module, then set
 * JDK_NON_UPGRADEABLE_MODULE to omit its version string.
 * <p>
 * If the loader is one of the built-in loaders (`boot`, `platform`, or `app`)
 * then set BUILTIN_CLASS_LOADER to omit the first element (`<loader>/`).
 */
private synchronized void computeFormat() {
    try {
        Class<?> cls = (Class<?>) declaringClassObject;
        ClassLoader loader = cls.getClassLoader0();
        Module m = cls.getModule();
        byte bits = 0;
        if (loader instanceof BuiltinClassLoader) {
            bits |= BUILTIN_CLASS_LOADER;
        }
        // in java.base)
        if (isHashedInJavaBase(m)) {
            bits |= JDK_NON_UPGRADEABLE_MODULE;
        }
        format = bits;
    } finally {
        // Class reference no longer needed, clear it
        declaringClassObject = null;
    }
}
Also used : BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) ResolvedModule(java.lang.module.ResolvedModule)

Example 5 with BuiltinClassLoader

use of jdk.internal.loader.BuiltinClassLoader in project Bytecoder by mirkosertic.

the class ModuleBootstrap method checkSplitPackages.

/**
 * Checks for split packages between modules defined to the built-in class
 * loaders.
 */
private static void checkSplitPackages(Configuration cf, Function<String, ClassLoader> clf) {
    Map<String, String> packageToModule = new HashMap<>();
    for (ResolvedModule resolvedModule : cf.modules()) {
        ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
        String name = descriptor.name();
        ClassLoader loader = clf.apply(name);
        if (loader == null || loader instanceof BuiltinClassLoader) {
            for (String p : descriptor.packages()) {
                String other = packageToModule.putIfAbsent(p, name);
                if (other != null) {
                    String msg = "Package " + p + " in both module " + name + " and module " + other;
                    throw new LayerInstantiationException(msg);
                }
            }
        }
    }
}
Also used : BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader) ModuleDescriptor(java.lang.module.ModuleDescriptor) ResolvedModule(java.lang.module.ResolvedModule) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) BuiltinClassLoader(jdk.internal.loader.BuiltinClassLoader)

Aggregations

BuiltinClassLoader (jdk.internal.loader.BuiltinClassLoader)6 ResolvedModule (java.lang.module.ResolvedModule)5 ModuleDescriptor (java.lang.module.ModuleDescriptor)2 ModuleReference (java.lang.module.ModuleReference)2 URL (java.net.URL)2 CallerSensitive (jdk.internal.reflect.CallerSensitive)2 IOException (java.io.IOException)1 Configuration (java.lang.module.Configuration)1 ModuleFinder (java.lang.module.ModuleFinder)1 URI (java.net.URI)1 AccessController (java.security.AccessController)1 PrivilegedAction (java.security.PrivilegedAction)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 BootLoader (jdk.internal.loader.BootLoader)1