1 /*
2 * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.reflect;
27
28 import java.lang.annotation.Annotation;
29 import java.lang.invoke.MethodHandle;
30 import java.lang.ref.WeakReference;
31
32 import jdk.internal.access.SharedSecrets;
33 import jdk.internal.misc.VM;
34 import jdk.internal.reflect.CallerSensitive;
35 import jdk.internal.reflect.Reflection;
36 import jdk.internal.reflect.ReflectionFactory;
37 import jdk.internal.vm.annotation.AOTRuntimeSetup;
38 import jdk.internal.vm.annotation.AOTSafeClassInitializer;
39
40 /**
41 * The {@code AccessibleObject} class is the base class for {@code Field},
42 * {@code Method}, and {@code Constructor} objects (known as <em>reflected
43 * objects</em>). It provides the ability to flag a reflected object as
44 * suppressing checks for Java language access control when it is used. This
45 * permits sophisticated applications with sufficient privilege, such as Java
46 * Object Serialization or other persistence mechanisms, to manipulate objects
47 * in a manner that would normally be prohibited.
48 *
49 * <p> Java language access control prevents use of private members outside
50 * their top-level class; package access members outside their package; protected members
51 * outside their package or subclasses; and public members outside their
52 * module unless they are declared in an {@link Module#isExported(String,Module)
53 * exported} package and the user {@link Module#canRead reads} their module. By
54 * default, Java language access control is enforced (with one variation) when
55 * {@code Field}s, {@code Method}s, or {@code Constructor}s are used to get or
56 * set fields, to invoke methods, or to create and initialize new instances of
57 * classes, respectively. Every reflected object checks that the code using it
58 * is in an appropriate class, package, or module. The check when invoked by
59 * <a href="{@docRoot}/../specs/jni/index.html">JNI code</a> with no Java
60 * class on the stack only succeeds if the member and the declaring class are
61 * public, and the class is in a package that is exported to all modules. </p>
62 *
63 * <p> The one variation from Java language access control is that the checks
64 * by reflected objects assume readability. That is, the module containing
65 * the use of a reflected object is assumed to read the module in which
66 * the underlying field, method, or constructor is declared. </p>
67 *
68 * <p> Whether the checks for Java language access control can be suppressed
69 * (and thus, whether access can be enabled) depends on whether the reflected
70 * object corresponds to a member in an exported or open package
71 * (see {@link #setAccessible(boolean)}). </p>
72 *
73 * @spec jni/index.html Java Native Interface Specification
74 * @jls 6.6 Access Control
75 * @since 1.2
76 */
77 @AOTSafeClassInitializer
78 public class AccessibleObject implements AnnotatedElement {
79 static {
80 runtimeSetup();
81 }
82
83 @AOTRuntimeSetup
84 private static void runtimeSetup() {
85 // AccessibleObject is initialized early in initPhase1
86 SharedSecrets.setJavaLangReflectAccess(new ReflectAccess());
87 }
88
89 /**
90 * Convenience method to set the {@code accessible} flag for an
91 * array of reflected objects.
92 *
93 * <p> This method may be used to enable access to all reflected objects in
94 * the array when access to each reflected object can be enabled as
95 * specified by {@link #setAccessible(boolean) setAccessible(boolean)}. </p>
96 *
97 * <p>A {@code SecurityException} is thrown if any of the elements of
98 * the input {@code array} is a {@link java.lang.reflect.Constructor}
99 * object for the class {@code java.lang.Class} and {@code flag} is true.
100 *
101 * @param array the array of AccessibleObjects
102 * @param flag the new value for the {@code accessible} flag
103 * in each object
104 * @throws InaccessibleObjectException if access cannot be enabled for all
105 * objects in the array
106 * @throws SecurityException if an element in the array is a constructor for {@code
107 * java.lang.Class}
108 */
109 @CallerSensitive
110 public static void setAccessible(AccessibleObject[] array, boolean flag) {
111 if (flag) {
112 Class<?> caller = Reflection.getCallerClass();
113 array = array.clone();
114 for (AccessibleObject ao : array) {
115 ao.checkCanSetAccessible(caller);
116 }
117 }
118 for (AccessibleObject ao : array) {
119 ao.setAccessible0(flag);
120 }
121 }
122
123 /**
124 * Set the {@code accessible} flag for this reflected object to
125 * the indicated boolean value. A value of {@code true} indicates that
126 * the reflected object should suppress checks for Java language access
127 * control when it is used. A value of {@code false} indicates that
128 * the reflected object should enforce checks for Java language access
129 * control when it is used, with the variation noted in the class description.
130 *
131 * <p> This method may be used by a caller in class {@code C} to enable
132 * access to a {@link Member member} of {@link Member#getDeclaringClass()
133 * declaring class} {@code D} if any of the following hold: </p>
134 *
135 * <ul>
136 * <li> {@code C} and {@code D} are in the same module. </li>
137 *
138 * <li> The member is {@code public} and {@code D} is {@code public} in
139 * a package that the module containing {@code D} {@link
140 * Module#isExported(String,Module) exports} to at least the module
141 * containing {@code C}. </li>
142 *
143 * <li> The member is {@code protected} {@code static}, {@code D} is
144 * {@code public} in a package that the module containing {@code D}
145 * exports to at least the module containing {@code C}, and {@code C}
146 * is a subclass of {@code D}. </li>
147 *
148 * <li> {@code D} is in a package that the module containing {@code D}
149 * {@link Module#isOpen(String,Module) opens} to at least the module
150 * containing {@code C}.
151 * All packages in unnamed and open modules are open to all modules and
152 * so this method always succeeds when {@code D} is in an unnamed or
153 * open module. </li>
154 * </ul>
155 *
156 * <p> This method may be used by <a href="{@docRoot}/../specs/jni/index.html">JNI code</a>
157 * with no caller class on the stack to enable access to a {@link Member member}
158 * of {@link Member#getDeclaringClass() declaring class} {@code D} if and only if:
159 * <ul>
160 * <li> The member is {@code public} and {@code D} is {@code public} in
161 * a package that the module containing {@code D} {@link
162 * Module#isExported(String,Module) exports} unconditionally. </li>
163 * </ul>
164 *
165 * <p> This method cannot be used to enable access to private members,
166 * members with default (package) access, protected instance members, or
167 * protected constructors when the declaring class is in a different module
168 * to the caller and the package containing the declaring class is not open
169 * to the caller's module. </p>
170 *
171 * <p> This method cannot be used to enable {@linkplain Field#set <em>write</em>}
172 * access to a <em>non-modifiable</em> final field. The following fields
173 * are non-modifiable:
174 * <ul>
175 * <li>static final fields declared in any class or interface</li>
176 * <li>final fields declared in a {@linkplain Class#isHidden() hidden class}</li>
177 * <li>final fields declared in a {@linkplain Class#isRecord() record}</li>
178 * </ul>
179 * <p> The {@code accessible} flag when {@code true} suppresses Java language access
180 * control checks to only enable {@linkplain Field#get <em>read</em>} access to
181 * these non-modifiable final fields.
182 *
183 * @param flag the new value for the {@code accessible} flag
184 * @throws InaccessibleObjectException if access cannot be enabled
185 *
186 * @spec jni/index.html Java Native Interface Specification
187 * @see #trySetAccessible
188 * @see java.lang.invoke.MethodHandles#privateLookupIn
189 */
190 @CallerSensitive // overrides in Method/Field/Constructor are @CS
191 public void setAccessible(boolean flag) {
192 setAccessible0(flag);
193 }
194
195 /**
196 * Sets the accessible flag and returns the new value
197 */
198 boolean setAccessible0(boolean flag) {
199 this.override = flag;
200 return flag;
201 }
202
203 /**
204 * Set the {@code accessible} flag for this reflected object to {@code true}
205 * if possible. This method sets the {@code accessible} flag, as if by
206 * invoking {@link #setAccessible(boolean) setAccessible(true)}, and returns
207 * the possibly-updated value for the {@code accessible} flag. If access
208 * cannot be enabled, i.e. the checks or Java language access control cannot
209 * be suppressed, this method returns {@code false} (as opposed to {@code
210 * setAccessible(true)} throwing {@code InaccessibleObjectException} when
211 * it fails).
212 *
213 * <p> This method is a no-op if the {@code accessible} flag for
214 * this reflected object is {@code true}.
215 *
216 * <p> For example, a caller can invoke {@code trySetAccessible}
217 * on a {@code Method} object for a private instance method
218 * {@code p.T::privateMethod} to suppress the checks for Java language access
219 * control when the {@code Method} is invoked.
220 * If {@code p.T} class is in a different module to the caller and
221 * package {@code p} is open to at least the caller's module,
222 * the code below successfully sets the {@code accessible} flag
223 * to {@code true}.
224 *
225 * <pre>
226 * {@code
227 * p.T obj = ....; // instance of p.T
228 * :
229 * Method m = p.T.class.getDeclaredMethod("privateMethod");
230 * if (m.trySetAccessible()) {
231 * m.invoke(obj);
232 * } else {
233 * // package p is not opened to the caller to access private member of T
234 * ...
235 * }
236 * }</pre>
237 *
238 * <p> If this method is invoked by <a href="{@docRoot}/../specs/jni/index.html">JNI code</a>
239 * with no caller class on the stack, the {@code accessible} flag can
240 * only be set if the member and the declaring class are public, and
241 * the class is in a package that is exported unconditionally. </p>
242 *
243 * @return {@code true} if the {@code accessible} flag is set to {@code true};
244 * {@code false} if access cannot be enabled.
245 *
246 * @spec jni/index.html Java Native Interface Specification
247 * @since 9
248 * @see java.lang.invoke.MethodHandles#privateLookupIn
249 */
250 @CallerSensitive
251 public final boolean trySetAccessible() {
252 if (override == true) return true;
253
254 // if it's not a Constructor, Method, Field then no access check
255 if (!Member.class.isInstance(this)) {
256 return setAccessible0(true);
257 }
258
259 // does not allow to suppress access check for Class's constructor
260 Class<?> declaringClass = ((Member) this).getDeclaringClass();
261 if (declaringClass == Class.class && this instanceof Constructor) {
262 return false;
263 }
264
265 if (checkCanSetAccessible(Reflection.getCallerClass(),
266 declaringClass,
267 false)) {
268 return setAccessible0(true);
269 } else {
270 return false;
271 }
272 }
273
274
275 /**
276 * If the given AccessibleObject is a {@code Constructor}, {@code Method}
277 * or {@code Field} then checks that its declaring class is in a package
278 * that can be accessed by the given caller of setAccessible.
279 */
280 void checkCanSetAccessible(Class<?> caller) {
281 // do nothing, needs to be overridden by Constructor, Method, Field
282 }
283
284 final void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
285 checkCanSetAccessible(caller, declaringClass, true);
286 }
287
288 private boolean checkCanSetAccessible(Class<?> caller,
289 Class<?> declaringClass,
290 boolean throwExceptionIfDenied) {
291 if (caller == MethodHandle.class) {
292 throw new IllegalCallerException(); // should not happen
293 }
294
295 if (caller == null) {
296 // No caller frame when a native thread attaches to the VM
297 // only allow access to a public accessible member
298 boolean canAccess = Reflection.verifyPublicMemberAccess(declaringClass, declaringClass.getModifiers());
299 if (!canAccess && throwExceptionIfDenied) {
300 throwInaccessibleObjectException(caller, declaringClass);
301 }
302 return canAccess;
303 }
304
305 Module callerModule = caller.getModule();
306 Module declaringModule = declaringClass.getModule();
307
308 if (callerModule == declaringModule) return true;
309 if (callerModule == Object.class.getModule()) return true;
310 if (!declaringModule.isNamed()) return true;
311
312 String pn = declaringClass.getPackageName();
313 int modifiers = ((Member)this).getModifiers();
314
315 // class is public and package is exported to caller
316 boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
317 if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
318 // member is public
319 if (Modifier.isPublic(modifiers)) {
320 return true;
321 }
322
323 // member is protected-static
324 if (Modifier.isProtected(modifiers)
325 && Modifier.isStatic(modifiers)
326 && isSubclassOf(caller, declaringClass)) {
327 return true;
328 }
329 }
330
331 // package is open to caller
332 if (declaringModule.isOpen(pn, callerModule)) {
333 return true;
334 }
335
336 if (throwExceptionIfDenied) {
337 throwInaccessibleObjectException(caller, declaringClass);
338 }
339 return false;
340 }
341
342 private void throwInaccessibleObjectException(Class<?> caller, Class<?> declaringClass) {
343 boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
344 String pn = declaringClass.getPackageName();
345 int modifiers = ((Member)this).getModifiers();
346
347 // not accessible
348 String msg = "Unable to make ";
349 if (this instanceof Field)
350 msg += "field ";
351 msg += this + " accessible";
352 msg += caller == null ? " by JNI attached native thread with no caller frame: " : ": ";
353 msg += declaringClass.getModule() + " does not \"";
354 if (isClassPublic && Modifier.isPublic(modifiers))
355 msg += "exports";
356 else
357 msg += "opens";
358 msg += " " + pn + "\"" ;
359 if (caller != null)
360 msg += " to " + caller.getModule();
361 InaccessibleObjectException e = new InaccessibleObjectException(msg);
362 if (printStackTraceWhenAccessFails()) {
363 e.printStackTrace(System.err);
364 }
365 throw e;
366 }
367
368 private boolean isSubclassOf(Class<?> queryClass, Class<?> ofClass) {
369 while (queryClass != null) {
370 if (queryClass == ofClass) {
371 return true;
372 }
373 queryClass = queryClass.getSuperclass();
374 }
375 return false;
376 }
377
378 /**
379 * Returns a short descriptive string to describe this object in log messages.
380 */
381 String toShortString() {
382 return toString();
383 }
384
385 /**
386 * Get the value of the {@code accessible} flag for this reflected object.
387 *
388 * @return the value of the object's {@code accessible} flag
389 *
390 * @deprecated
391 * This method is deprecated because its name hints that it checks
392 * if the reflected object is accessible when it actually indicates
393 * if the checks for Java language access control are suppressed.
394 * This method may return {@code false} on a reflected object that is
395 * accessible to the caller. To test if this reflected object is accessible,
396 * it should use {@link #canAccess(Object)}.
397 */
398 @Deprecated(since="9")
399 public boolean isAccessible() {
400 return override;
401 }
402
403 /**
404 * Test if the caller can access this reflected object. If this reflected
405 * object corresponds to an instance method or field then this method tests
406 * if the caller can access the given {@code obj} with the reflected object.
407 * For instance methods or fields then the {@code obj} argument must be an
408 * instance of the {@link Member#getDeclaringClass() declaring class}. For
409 * static members and constructors then {@code obj} must be {@code null}.
410 *
411 * <p> This method returns {@code true} if the {@code accessible} flag
412 * is set to {@code true}, i.e. the checks for Java language access control
413 * are suppressed, or if the caller can access the member as
414 * specified in <cite>The Java Language Specification</cite>,
415 * with the variation noted in the class description.
416 * If this method is invoked by <a href="{@docRoot}/../specs/jni/index.html">JNI code</a>
417 * with no caller class on the stack, this method returns {@code true}
418 * if the member and the declaring class are public, and the class is in
419 * a package that is exported unconditionally. </p>
420 *
421 * @param obj an instance object of the declaring class of this reflected
422 * object if it is an instance method or field
423 *
424 * @return {@code true} if the caller can access this reflected object.
425 *
426 * @throws IllegalArgumentException
427 * <ul>
428 * <li> if this reflected object is a static member or constructor and
429 * the given {@code obj} is non-{@code null}, or </li>
430 * <li> if this reflected object is an instance method or field
431 * and the given {@code obj} is {@code null} or of type
432 * that is not a subclass of the {@link Member#getDeclaringClass()
433 * declaring class} of the member.</li>
434 * </ul>
435 *
436 * @spec jni/index.html Java Native Interface Specification
437 * @since 9
438 * @jls 6.6 Access Control
439 * @see #trySetAccessible
440 * @see #setAccessible(boolean)
441 */
442 @CallerSensitive
443 public final boolean canAccess(Object obj) {
444 if (!Member.class.isInstance(this)) {
445 return override;
446 }
447
448 Class<?> declaringClass = ((Member) this).getDeclaringClass();
449 int modifiers = ((Member) this).getModifiers();
450 if (!Modifier.isStatic(modifiers) &&
451 (this instanceof Method || this instanceof Field)) {
452 if (obj == null) {
453 throw new IllegalArgumentException("null object for " + this);
454 }
455 // if this object is an instance member, the given object
456 // must be a subclass of the declaring class of this reflected object
457 if (!declaringClass.isInstance(obj)) {
458 throw new IllegalArgumentException("object is not an instance of "
459 + declaringClass.getName());
460 }
461 } else if (obj != null) {
462 throw new IllegalArgumentException("non-null object for " + this);
463 }
464
465 // access check is suppressed
466 if (override) return true;
467
468 Class<?> caller = Reflection.getCallerClass();
469 Class<?> targetClass;
470 if (this instanceof Constructor) {
471 targetClass = declaringClass;
472 } else {
473 targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
474 }
475 return verifyAccess(caller, declaringClass, targetClass, modifiers);
476 }
477
478 /**
479 * Constructor: only used by the Java Virtual Machine.
480 */
481 @Deprecated(since="17")
482 protected AccessibleObject() {}
483
484 // Indicates whether language-level access checks are overridden
485 // by this object. Initializes to "false". This field is used by
486 // Field, Method, and Constructor.
487 //
488 // NOTE: for security purposes, this field must not be visible
489 // outside this package.
490 boolean override;
491
492 // Reflection factory used by subclasses for creating field,
493 // method, and constructor accessors. Note that this is called
494 // very early in the bootstrapping process.
495 static final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
496
497 /**
498 * {@inheritDoc}
499 *
500 * <p> Note that any annotation returned by this method is a
501 * declaration annotation.
502 *
503 * @implSpec
504 * The default implementation throws {@link
505 * UnsupportedOperationException}; subclasses should override this method.
506 *
507 * @throws NullPointerException {@inheritDoc}
508 * @since 1.5
509 */
510 @Override
511 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
512 throw new UnsupportedOperationException("All subclasses should override this method");
513 }
514
515 /**
516 * {@inheritDoc}
517 *
518 * @throws NullPointerException {@inheritDoc}
519 * @since 1.5
520 */
521 @Override
522 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
523 return AnnotatedElement.super.isAnnotationPresent(annotationClass);
524 }
525
526 /**
527 * {@inheritDoc}
528 *
529 * <p> Note that any annotations returned by this method are
530 * declaration annotations.
531 *
532 * @implSpec
533 * The default implementation throws {@link
534 * UnsupportedOperationException}; subclasses should override this method.
535 *
536 * @throws NullPointerException {@inheritDoc}
537 * @since 1.8
538 */
539 @Override
540 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
541 throw new UnsupportedOperationException("All subclasses should override this method");
542 }
543
544 /**
545 * {@inheritDoc}
546 *
547 * <p> Note that any annotations returned by this method are
548 * declaration annotations.
549 *
550 * @since 1.5
551 */
552 @Override
553 public Annotation[] getAnnotations() {
554 return getDeclaredAnnotations();
555 }
556
557 /**
558 * {@inheritDoc}
559 *
560 * <p> Note that any annotation returned by this method is a
561 * declaration annotation.
562 *
563 * @throws NullPointerException {@inheritDoc}
564 * @since 1.8
565 */
566 @Override
567 public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
568 // Only annotations on classes are inherited, for all other
569 // objects getDeclaredAnnotation is the same as
570 // getAnnotation.
571 return getAnnotation(annotationClass);
572 }
573
574 /**
575 * {@inheritDoc}
576 *
577 * <p> Note that any annotations returned by this method are
578 * declaration annotations.
579 *
580 * @throws NullPointerException {@inheritDoc}
581 * @since 1.8
582 */
583 @Override
584 public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
585 // Only annotations on classes are inherited, for all other
586 // objects getDeclaredAnnotationsByType is the same as
587 // getAnnotationsByType.
588 return getAnnotationsByType(annotationClass);
589 }
590
591 /**
592 * {@inheritDoc}
593 *
594 * <p> Note that any annotations returned by this method are
595 * declaration annotations.
596 *
597 * @implSpec
598 * The default implementation throws {@link
599 * UnsupportedOperationException}; subclasses should override this method.
600 *
601 * @since 1.5
602 */
603 @Override
604 public Annotation[] getDeclaredAnnotations() {
605 throw new UnsupportedOperationException("All subclasses should override this method");
606 }
607
608 // Shared access checking logic.
609
610 // For non-public members or members in package-private classes,
611 // it is necessary to perform somewhat expensive access checks.
612 // If the access check succeeds for a given class, it will
613 // always succeed; we speed up the check in the common case by
614 // remembering the last Class for which the check succeeded.
615 //
616 // The simple access check for Constructor is to see if
617 // the caller has already been seen, verified, and cached.
618 //
619 // A more complicated access check cache is needed for Method and Field
620 // The cache can be either null (empty cache), {caller,targetClass} pair,
621 // or a caller (with targetClass implicitly equal to memberClass).
622 // In the {caller,targetClass} case, the targetClass is always different
623 // from the memberClass.
624 volatile Object accessCheckCache;
625
626 private static class Cache {
627 final WeakReference<Class<?>> callerRef;
628 final WeakReference<Class<?>> targetRef;
629
630 Cache(Class<?> caller, Class<?> target) {
631 this.callerRef = new WeakReference<>(caller);
632 this.targetRef = new WeakReference<>(target);
633 }
634
635 boolean isCacheFor(Class<?> caller, Class<?> refc) {
636 return callerRef.refersTo(caller) && targetRef.refersTo(refc);
637 }
638
639 static Object protectedMemberCallerCache(Class<?> caller, Class<?> refc) {
640 return new Cache(caller, refc);
641 }
642 }
643
644 /*
645 * Returns true if the previous access check was verified for the
646 * given caller accessing a protected member with an instance of
647 * the given targetClass where the target class is different than
648 * the declaring member class.
649 */
650 private boolean isAccessChecked(Class<?> caller, Class<?> targetClass) {
651 Object cache = accessCheckCache; // read volatile
652 if (cache instanceof Cache c) {
653 return c.isCacheFor(caller, targetClass);
654 }
655 return false;
656 }
657
658 /*
659 * Returns true if the previous access check was verified for the
660 * given caller accessing a static member or an instance member of
661 * the target class that is the same as the declaring member class.
662 */
663 private boolean isAccessChecked(Class<?> caller) {
664 Object cache = accessCheckCache; // read volatile
665 if (cache instanceof WeakReference) {
666 @SuppressWarnings("unchecked")
667 WeakReference<Class<?>> ref = (WeakReference<Class<?>>) cache;
668 return ref.refersTo(caller);
669 }
670 return false;
671 }
672
673 final void checkAccess(Class<?> caller, Class<?> memberClass,
674 Class<?> targetClass, int modifiers)
675 throws IllegalAccessException
676 {
677 if (!verifyAccess(caller, memberClass, targetClass, modifiers)) {
678 IllegalAccessException e = Reflection.newIllegalAccessException(
679 caller, memberClass, targetClass, modifiers);
680 if (printStackTraceWhenAccessFails()) {
681 e.printStackTrace(System.err);
682 }
683 throw e;
684 }
685 }
686
687 final boolean verifyAccess(Class<?> caller, Class<?> memberClass,
688 Class<?> targetClass, int modifiers)
689 {
690 if (caller == memberClass) { // quick check
691 return true; // ACCESS IS OK
692 }
693 if (targetClass != null // instance member or constructor
694 && Modifier.isProtected(modifiers)
695 && targetClass != memberClass) {
696 if (isAccessChecked(caller, targetClass)) {
697 return true; // ACCESS IS OK
698 }
699 } else if (isAccessChecked(caller)) {
700 // Non-protected case (or targetClass == memberClass or static member).
701 return true; // ACCESS IS OK
702 }
703
704 // If no return, fall through to the slow path.
705 return slowVerifyAccess(caller, memberClass, targetClass, modifiers);
706 }
707
708 // Keep all this slow stuff out of line:
709 private boolean slowVerifyAccess(Class<?> caller, Class<?> memberClass,
710 Class<?> targetClass, int modifiers)
711 {
712
713 if (caller == null) {
714 // No caller frame when a native thread attaches to the VM
715 // only allow access to a public accessible member
716 return Reflection.verifyPublicMemberAccess(memberClass, modifiers);
717 }
718
719 if (!Reflection.verifyMemberAccess(caller, memberClass, targetClass, modifiers)) {
720 // access denied
721 return false;
722 }
723
724 // Success: Update the cache.
725 Object cache = (targetClass != null
726 && Modifier.isProtected(modifiers)
727 && targetClass != memberClass)
728 ? Cache.protectedMemberCallerCache(caller, targetClass)
729 : new WeakReference<>(caller);
730 accessCheckCache = cache; // write volatile
731 return true;
732 }
733
734 // true to print a stack trace when access fails
735 private static volatile boolean printStackWhenAccessFails;
736
737 // true if printStack* values are initialized
738 private static volatile boolean printStackPropertiesSet;
739
740 /**
741 * Returns true if a stack trace should be printed when access fails.
742 */
743 private static boolean printStackTraceWhenAccessFails() {
744 if (!printStackPropertiesSet && VM.initLevel() >= 1) {
745 String s = System.getProperty("sun.reflect.debugModuleAccessChecks");
746 if (s != null) {
747 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
748 }
749 printStackPropertiesSet = true;
750 }
751 return printStackWhenAccessFails;
752 }
753
754 /**
755 * Returns the root AccessibleObject; or null if this object is the root.
756 *
757 * All subclasses override this method.
758 */
759 AccessibleObject getRoot() {
760 throw new InternalError();
761 }
762 }