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