use of jdk.internal.reflect.CallerSensitive in project Bytecoder by mirkosertic.
the class Class method getResource.
/**
* 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#getSystemResource}.
*
* <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.net.URL} object; {@code null} if no resource with
* this name is found, the resource cannot be located by a URL, 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}
* @since 1.1
* @revised 9
* @spec JPMS
*/
@CallerSensitive
public URL getResource(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 {
if (cl == null) {
return BootLoader.findResource(mn, name);
} else {
return cl.findResource(mn, name);
}
} catch (IOException ioe) {
return null;
}
}
// unnamed module
ClassLoader cl = getClassLoader0();
if (cl == null) {
return ClassLoader.getSystemResource(name);
} else {
return cl.getResource(name);
}
}
use of jdk.internal.reflect.CallerSensitive in project Bytecoder by mirkosertic.
the class Module method addOpens.
/**
* If this module has <em>opened</em> a package to at least the caller
* module then update this module to open the package to the given module.
* Opening a package with this method allows all types in the package,
* and all their members, not just public types and their public members,
* to be reflected on by the given module when using APIs that support
* private access or a way to bypass or suppress default Java language
* access control checks.
*
* <p> This method has no effect if the package is already <em>open</em>
* to the given module. </p>
*
* @apiNote This method can be used for cases where a <em>consumer
* module</em> uses a qualified opens to open a package to an <em>API
* module</em> but where the reflective access to the members of classes in
* the consumer module is delegated to code in another module. Code in the
* API module can use this method to open the package in the consumer module
* to the other module.
*
* @param pn
* The package name
* @param other
* The module
*
* @return this module
*
* @throws IllegalArgumentException
* If {@code pn} is {@code null}, or this is a named module and the
* package {@code pn} is not a package in this module
* @throws IllegalCallerException
* If this is a named module and this module has not opened the
* package to at least the caller's module
*
* @see #isOpen(String,Module)
* @see AccessibleObject#setAccessible(boolean)
* @see java.lang.invoke.MethodHandles#privateLookupIn
*/
@CallerSensitive
public Module addOpens(String pn, Module other) {
if (pn == null)
throw new IllegalArgumentException("package is null");
Objects.requireNonNull(other);
if (isNamed()) {
Module caller = getCallerModule(Reflection.getCallerClass());
if (caller != this && (caller == null || !isOpen(pn, caller)))
throw new IllegalCallerException(pn + " is not open to " + caller);
implAddExportsOrOpens(pn, other, /*open*/
true, /*syncVM*/
true);
}
return this;
}
use of jdk.internal.reflect.CallerSensitive in project Bytecoder by mirkosertic.
the class Module method addReads.
/**
* If the caller's module is this module then update this module to read
* the given module.
*
* This method is a no-op if {@code other} is this module (all modules read
* themselves), this module is an unnamed module (as unnamed modules read
* all modules), or this module already reads {@code other}.
*
* @implNote <em>Read edges</em> added by this method are <em>weak</em> and
* do not prevent {@code other} from being GC'ed when this module is
* strongly reachable.
*
* @param other
* The other module
*
* @return this module
*
* @throws IllegalCallerException
* If this is a named module and the caller's module is not this
* module
*
* @see #canRead
*/
@CallerSensitive
public Module addReads(Module other) {
Objects.requireNonNull(other);
if (this.isNamed()) {
Module caller = getCallerModule(Reflection.getCallerClass());
if (caller != this) {
throw new IllegalCallerException(caller + " != " + this);
}
implAddReads(other, true);
}
return this;
}
use of jdk.internal.reflect.CallerSensitive 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.reflect.CallerSensitive in project Bytecoder by mirkosertic.
the class Module method addExports.
/**
* If the caller's module is this module then update this module to export
* the given package to the given module.
*
* <p> This method has no effect if the package is already exported (or
* <em>open</em>) to the given module. </p>
*
* @apiNote As specified in section 5.4.3 of the <cite>The Java™
* Virtual Machine Specification </cite>, if an attempt to resolve a
* symbolic reference fails because of a linkage error, then subsequent
* attempts to resolve the reference always fail with the same error that
* was thrown as a result of the initial resolution attempt.
*
* @param pn
* The package name
* @param other
* The module
*
* @return this module
*
* @throws IllegalArgumentException
* If {@code pn} is {@code null}, or this is a named module and the
* package {@code pn} is not a package in this module
* @throws IllegalCallerException
* If this is a named module and the caller's module is not this
* module
*
* @jvms 5.4.3 Resolution
* @see #isExported(String,Module)
*/
@CallerSensitive
public Module addExports(String pn, Module other) {
if (pn == null)
throw new IllegalArgumentException("package is null");
Objects.requireNonNull(other);
if (isNamed()) {
Module caller = getCallerModule(Reflection.getCallerClass());
if (caller != this) {
throw new IllegalCallerException(caller + " != " + this);
}
implAddExportsOrOpens(pn, other, /*open*/
false, /*syncVM*/
true);
}
return this;
}
Aggregations