use of jdk.internal.module.IllegalAccessLogger in project Bytecoder by mirkosertic.
the class MethodHandles method privateLookupIn.
/**
* Returns a {@link Lookup lookup object} with full capabilities to emulate all
* supported bytecode behaviors, including <a href="MethodHandles.Lookup.html#privacc">
* private access</a>, on a target class.
* This method checks that a caller, specified as a {@code Lookup} object, is allowed to
* do <em>deep reflection</em> on the target class. If {@code m1} is the module containing
* the {@link Lookup#lookupClass() lookup class}, and {@code m2} is the module containing
* the target class, then this check ensures that
* <ul>
* <li>{@code m1} {@link Module#canRead reads} {@code m2}.</li>
* <li>{@code m2} {@link Module#isOpen(String,Module) opens} the package containing
* the target class to at least {@code m1}.</li>
* <li>The lookup has the {@link Lookup#MODULE MODULE} lookup mode.</li>
* </ul>
* <p>
* If there is a security manager, its {@code checkPermission} method is called to
* check {@code ReflectPermission("suppressAccessChecks")}.
* @apiNote The {@code MODULE} lookup mode serves to authenticate that the lookup object
* was created by code in the caller module (or derived from a lookup object originally
* created by the caller). A lookup object with the {@code MODULE} lookup mode can be
* shared with trusted parties without giving away {@code PRIVATE} and {@code PACKAGE}
* access to the caller.
* @param targetClass the target class
* @param lookup the caller lookup object
* @return a lookup object for the target class, with private access
* @throws IllegalArgumentException if {@code targetClass} is a primitve type or array class
* @throws NullPointerException if {@code targetClass} or {@code caller} is {@code null}
* @throws IllegalAccessException if the access check specified above fails
* @throws SecurityException if denied by the security manager
* @since 9
* @spec JPMS
* @see Lookup#dropLookupMode
*/
public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(ACCESS_PERMISSION);
if (targetClass.isPrimitive())
throw new IllegalArgumentException(targetClass + " is a primitive class");
if (targetClass.isArray())
throw new IllegalArgumentException(targetClass + " is an array class");
Module targetModule = targetClass.getModule();
Module callerModule = lookup.lookupClass().getModule();
if (!callerModule.canRead(targetModule))
throw new IllegalAccessException(callerModule + " does not read " + targetModule);
if (targetModule.isNamed()) {
String pn = targetClass.getPackageName();
assert pn.length() > 0 : "unnamed package cannot be in named module";
if (!targetModule.isOpen(pn, callerModule))
throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
}
if ((lookup.lookupModes() & Lookup.MODULE) == 0)
throw new IllegalAccessException("lookup does not have MODULE lookup mode");
if (!callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
logger.logIfOpenedForIllegalAccess(lookup, targetClass);
}
}
return new Lookup(targetClass);
}
use of jdk.internal.module.IllegalAccessLogger in project Bytecoder by mirkosertic.
the class AccessibleObject method logIfOpenedForIllegalAccess.
private void logIfOpenedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
Module callerModule = caller.getModule();
Module targetModule = declaringClass.getModule();
// callerModule is null during early startup
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
logger.logIfOpenedForIllegalAccess(caller, declaringClass, this::toShortString);
}
}
}
use of jdk.internal.module.IllegalAccessLogger in project Bytecoder by mirkosertic.
the class AccessibleObject method logIfExportedForIllegalAccess.
private void logIfExportedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
Module callerModule = caller.getModule();
Module targetModule = declaringClass.getModule();
// callerModule is null during early startup
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
logger.logIfExportedForIllegalAccess(caller, declaringClass, this::toShortString);
}
}
}
use of jdk.internal.module.IllegalAccessLogger in project Bytecoder by mirkosertic.
the class Module method implAddExportsOrOpens.
/**
* Updates a module to export or open a module to another module.
*
* If {@code syncVM} is {@code true} then the VM is notified.
*/
private void implAddExportsOrOpens(String pn, Module other, boolean open, boolean syncVM) {
Objects.requireNonNull(other);
Objects.requireNonNull(pn);
// all packages are open in unnamed, open, and automatic modules
if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
return;
// check if the package is already exported/open to other
if (implIsExportedOrOpen(pn, other, open)) {
// if the package is exported/open for illegal access then we need
// to record that it has also been exported/opened reflectively so
// that the IllegalAccessLogger doesn't emit a warning.
boolean needToAdd = false;
if (!other.isNamed()) {
IllegalAccessLogger l = IllegalAccessLogger.illegalAccessLogger();
if (l != null) {
if (open) {
needToAdd = l.isOpenForIllegalAccess(this, pn);
} else {
needToAdd = l.isExportedForIllegalAccess(this, pn);
}
}
}
if (!needToAdd) {
// nothing to do
return;
}
}
// can only export a package in the module
if (!descriptor.packages().contains(pn)) {
throw new IllegalArgumentException("package " + pn + " not in contents");
}
// update VM first, just in case it fails
if (syncVM) {
if (other == EVERYONE_MODULE) {
addExportsToAll0(this, pn);
} else if (other == ALL_UNNAMED_MODULE) {
addExportsToAllUnnamed0(this, pn);
} else {
addExports0(this, pn, other);
}
}
// add package name to exports if absent
Map<String, Boolean> map = ReflectionData.exports.computeIfAbsent(this, other, (m1, m2) -> new ConcurrentHashMap<>());
if (open) {
// may need to promote from FALSE to TRUE
map.put(pn, Boolean.TRUE);
} else {
map.putIfAbsent(pn, Boolean.FALSE);
}
}
Aggregations