< prev index next >
src/java.base/share/classes/java/lang/reflect/AccessibleObject.java
Print this page
@@ -26,13 +26,15 @@
package java.lang.reflect;
import java.lang.annotation.Annotation;
import java.security.AccessController;
+import jdk.internal.misc.VM;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
+import sun.security.action.GetPropertyAction;
/**
* The AccessibleObject class is the base class for Field, Method and
* Constructor objects. It provides the ability to flag a reflected
* object as suppressing default Java language access control checks
@@ -170,12 +172,14 @@
if (callerModule == Object.class.getModule()) return;
if (!declaringModule.isNamed()) return;
// package is open to caller
String pn = packageName(declaringClass);
- if (declaringModule.isOpen(pn, callerModule))
+ if (declaringModule.isOpen(pn, callerModule)) {
+ printStackTraceIfOpenedReflectively(declaringModule, pn, callerModule);
return;
+ }
// package is exported to caller and class/member is public
boolean isExported = declaringModule.isExported(pn, callerModule);
boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
int modifiers;
@@ -183,12 +187,14 @@
modifiers = ((Executable) this).getModifiers();
} else {
modifiers = ((Field) this).getModifiers();
}
boolean isMemberPublic = Modifier.isPublic(modifiers);
- if (isExported && isClassPublic && isMemberPublic)
+ if (isExported && isClassPublic && isMemberPublic) {
+ printStackTraceIfExportedReflectively(declaringModule, pn, callerModule);
return;
+ }
// not accessible
String msg = "Unable to make ";
if (this instanceof Field)
msg += "field ";
@@ -196,11 +202,55 @@
if (isClassPublic && isMemberPublic)
msg += "exports";
else
msg += "opens";
msg += " " + pn + "\" to " + callerModule;
- Reflection.throwInaccessibleObjectException(msg);
+ InaccessibleObjectException e = new InaccessibleObjectException(msg);
+ if (Reflection.printStackTraceWhenAccessFails()) {
+ e.printStackTrace(System.err);
+ }
+ throw e;
+ }
+
+ private void printStackTraceIfOpenedReflectively(Module module,
+ String pn,
+ Module other) {
+ printStackTraceIfExposedReflectively(module, pn, other, true);
+ }
+
+ private void printStackTraceIfExportedReflectively(Module module,
+ String pn,
+ Module other) {
+ printStackTraceIfExposedReflectively(module, pn, other, false);
+ }
+
+ private static class WARNING extends Exception {
+
+ private static final long serialVersionUID = 42L;
+
+ private WARNING(String msg) {
+ super(msg);
+ }
+
+ public String toString() {
+ return "WARNING: " + getMessage();
+ }
+
+ }
+
+ private void printStackTraceIfExposedReflectively(Module module,
+ String pn,
+ Module other,
+ boolean open) {
+ if (Reflection.printStackTraceWhenAccessSucceeds()
+ && !module.isStaticallyExportedOrOpen(pn, other, open)) {
+ String msg = other + " allowed to invoke setAccessible on ";
+ if (this instanceof Field)
+ msg += "field ";
+ msg += this;
+ new WARNING(msg).printStackTrace(System.err);
+ }
}
/**
* Returns the package name of the given class.
*/
< prev index next >