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