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