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 }