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>'\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>'\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);
}
}
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"));
}
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;
}
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;
}
}
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);
}
}
}
}
}
Aggregations