< prev index next >

src/java.base/share/classes/jdk/internal/reflect/Reflection.java

Print this page




  87 
  88     /**
  89      * Ensures that access to a member is granted and throws
  90      * IllegalAccessException if not.
  91      *
  92      * @param currentClass the class performing the access
  93      * @param memberClass the declaring class of the member being accessed
  94      * @param targetClass the class of target object if accessing instance
  95      *                    field or method;
  96      *                    or the declaring class if accessing constructor;
  97      *                    or null if accessing static field or method
  98      * @param modifiers the member's access modifiers
  99      * @throws IllegalAccessException if access to member is denied
 100      */
 101     public static void ensureMemberAccess(Class<?> currentClass,
 102                                           Class<?> memberClass,
 103                                           Class<?> targetClass,
 104                                           int modifiers)
 105         throws IllegalAccessException
 106     {
 107         if (currentClass == null || memberClass == null) {
 108             throw new InternalError();
 109         }
 110 
 111         if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
 112             throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
 113         }
 114     }
 115 
 116     /**
 117      * Verify access to a member, returning {@code false} if no access









 118      */
 119     public static boolean verifyMemberAccess(Class<?> currentClass,
 120                                              Class<?> memberClass,
 121                                              Class<?> targetClass,
 122                                              int modifiers)
 123     {
 124         // Verify that currentClass can access a field, method, or
 125         // constructor of memberClass, where that member's access bits are
 126         // "modifiers".
 127 
 128         boolean gotIsSameClassPackage = false;
 129         boolean isSameClassPackage = false;
 130 
 131         if (currentClass == memberClass) {
 132             // Always succeeds
 133             return true;
 134         }
 135 
 136         if (!verifyModuleAccess(currentClass, memberClass)) {
 137             return false;
 138         }
 139 



 140         if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
 141             isSameClassPackage = isSameClassPackage(currentClass, memberClass);
 142             gotIsSameClassPackage = true;
 143             if (!isSameClassPackage) {
 144                 return false;
 145             }
 146         }
 147 
 148         // At this point we know that currentClass can access memberClass.
 149 
 150         if (Modifier.isPublic(modifiers)) {
 151             return true;
 152         }
 153 
 154         boolean successSoFar = false;
 155 
 156         if (Modifier.isProtected(modifiers)) {
 157             // See if currentClass is a subclass of memberClass
 158             if (isSubclassOf(currentClass, memberClass)) {
 159                 successSoFar = true;


 180         // and protected constructors: JLS 6.6.2
 181         if (targetClass != null && Modifier.isProtected(modifiers) &&
 182             targetClass != currentClass)
 183         {
 184             if (!gotIsSameClassPackage) {
 185                 isSameClassPackage = isSameClassPackage(currentClass, memberClass);
 186                 gotIsSameClassPackage = true;
 187             }
 188             if (!isSameClassPackage) {
 189                 if (!isSubclassOf(targetClass, currentClass)) {
 190                     return false;
 191                 }
 192             }
 193         }
 194 
 195         return true;
 196     }
 197 
 198     /**
 199      * Returns {@code true} if memberClass's's module exports memberClass's
 200      * package to currentClass's module.
 201      */
 202     public static boolean verifyModuleAccess(Class<?> currentClass,
 203                                              Class<?> memberClass) {
 204         return verifyModuleAccess(currentClass.getModule(), memberClass);
 205     }
 206 
 207     public static boolean verifyModuleAccess(Module currentModule, Class<?> memberClass) {




 208         Module memberModule = memberClass.getModule();
 209 
 210         // module may be null during startup (initLevel 0)
 211         if (currentModule == memberModule)
 212            return true;  // same module (named or unnamed)
 213 
 214         String pkg = memberClass.getPackageName();
 215         boolean allowed = memberModule.isExported(pkg, currentModule);
 216         if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
 217             if (!SharedSecrets.getJavaLangReflectModuleAccess()
 218                     .isStaticallyExported(memberModule, pkg, currentModule)) {
 219                 String msg = currentModule + " allowed access to member of " + memberClass;
 220                 new Exception(msg).printStackTrace(System.err);
 221             }
 222         }
 223         return allowed;
 224     }
 225 
 226     /**
 227      * Returns true if two classes in the same package.
 228      */
 229     private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
 230         if (c1.getClassLoader() != c2.getClassLoader())
 231             return false;
 232         return Objects.equals(c1.getPackageName(), c2.getPackageName());


 361             if (s != null) {
 362                 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
 363                 printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
 364             }
 365             printStackPropertiesSet = true;
 366         }
 367     }
 368 
 369     public static boolean printStackTraceWhenAccessFails() {
 370         ensurePrintStackPropertiesSet();
 371         return printStackWhenAccessFails;
 372     }
 373 
 374     public static boolean printStackTraceWhenAccessSucceeds() {
 375         ensurePrintStackPropertiesSet();
 376         return printStackWhenAccessSucceeds;
 377     }
 378 
 379     /**
 380      * Throws IllegalAccessException with the an exception message based on
 381      * the access that is denied.


 382      */
 383     private static void throwIllegalAccessException(Class<?> currentClass,
 384                                                     Class<?> memberClass,
 385                                                     Object target,
 386                                                     int modifiers)
 387         throws IllegalAccessException
 388     {
 389         String currentSuffix = "";
 390         String memberSuffix = "";
 391         Module m1 = currentClass.getModule();
 392         if (m1.isNamed())
 393             currentSuffix = " (in " + m1 + ")";
 394         Module m2 = memberClass.getModule();
 395         if (m2.isNamed())
 396             memberSuffix = " (in " + m2 + ")";
 397 
 398         String memberPackageName = memberClass.getPackageName();
 399 
 400         String msg = currentClass + currentSuffix + " cannot access ";
 401         if (m2.isExported(memberPackageName, m1)) {
 402 
 403             // module access okay so include the modifiers in the message
 404             msg += "a member of " + memberClass + memberSuffix +
 405                     " with modifiers \"" + Modifier.toString(modifiers) + "\"";




  87 
  88     /**
  89      * Ensures that access to a member is granted and throws
  90      * IllegalAccessException if not.
  91      *
  92      * @param currentClass the class performing the access
  93      * @param memberClass the declaring class of the member being accessed
  94      * @param targetClass the class of target object if accessing instance
  95      *                    field or method;
  96      *                    or the declaring class if accessing constructor;
  97      *                    or null if accessing static field or method
  98      * @param modifiers the member's access modifiers
  99      * @throws IllegalAccessException if access to member is denied
 100      */
 101     public static void ensureMemberAccess(Class<?> currentClass,
 102                                           Class<?> memberClass,
 103                                           Class<?> targetClass,
 104                                           int modifiers)
 105         throws IllegalAccessException
 106     {




 107         if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
 108             throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
 109         }
 110     }
 111 
 112     /**
 113      * Verify access to a member and return {@code true} if it is granted.
 114      *
 115      * @param currentClass the class performing the access
 116      * @param memberClass the declaring class of the member being accessed
 117      * @param targetClass the class of target object if accessing instance
 118      *                    field or method;
 119      *                    or the declaring class if accessing constructor;
 120      *                    or null if accessing static field or method
 121      * @param modifiers the member's access modifiers
 122      * @return {@code true} if access to member is granted
 123      */
 124     public static boolean verifyMemberAccess(Class<?> currentClass,
 125                                              Class<?> memberClass,
 126                                              Class<?> targetClass,
 127                                              int modifiers)
 128     {
 129         Objects.requireNonNull(currentClass, "currentClass");
 130         Objects.requireNonNull(memberClass, "memberClass");




 131 
 132         if (currentClass == memberClass) {
 133             // Always succeeds
 134             return true;
 135         }
 136 
 137         if (!verifyModuleAccess(currentClass.getModule(), memberClass)) {
 138             return false;
 139         }
 140 
 141         boolean gotIsSameClassPackage = false;
 142         boolean isSameClassPackage = false;
 143 
 144         if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
 145             isSameClassPackage = isSameClassPackage(currentClass, memberClass);
 146             gotIsSameClassPackage = true;
 147             if (!isSameClassPackage) {
 148                 return false;
 149             }
 150         }
 151 
 152         // At this point we know that currentClass can access memberClass.
 153 
 154         if (Modifier.isPublic(modifiers)) {
 155             return true;
 156         }
 157 
 158         boolean successSoFar = false;
 159 
 160         if (Modifier.isProtected(modifiers)) {
 161             // See if currentClass is a subclass of memberClass
 162             if (isSubclassOf(currentClass, memberClass)) {
 163                 successSoFar = true;


 184         // and protected constructors: JLS 6.6.2
 185         if (targetClass != null && Modifier.isProtected(modifiers) &&
 186             targetClass != currentClass)
 187         {
 188             if (!gotIsSameClassPackage) {
 189                 isSameClassPackage = isSameClassPackage(currentClass, memberClass);
 190                 gotIsSameClassPackage = true;
 191             }
 192             if (!isSameClassPackage) {
 193                 if (!isSubclassOf(targetClass, currentClass)) {
 194                     return false;
 195                 }
 196             }
 197         }
 198 
 199         return true;
 200     }
 201 
 202     /**
 203      * Returns {@code true} if memberClass's's module exports memberClass's
 204      * package to currentModule.
 205      */





 206     public static boolean verifyModuleAccess(Module currentModule, Class<?> memberClass) {
 207         if (VM.isModuleSystemInited())
 208             Objects.requireNonNull(currentModule, "currentModule");
 209         Objects.requireNonNull(memberClass, "memberClass");
 210 
 211         Module memberModule = memberClass.getModule();
 212 
 213         // module may be null during startup (initLevel < VM.MODULE_SYSTEM_INITED)
 214         if (currentModule == memberModule)
 215            return true;  // same module (named or unnamed) or both are null
 216 
 217         String pkg = memberClass.getPackageName();
 218         boolean allowed = memberModule.isExported(pkg, currentModule);
 219         if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
 220             if (!SharedSecrets.getJavaLangReflectModuleAccess()
 221                     .isStaticallyExported(memberModule, pkg, currentModule)) {
 222                 String msg = currentModule + " allowed access to member of " + memberClass;
 223                 new Exception(msg).printStackTrace(System.err);
 224             }
 225         }
 226         return allowed;
 227     }
 228 
 229     /**
 230      * Returns true if two classes in the same package.
 231      */
 232     private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
 233         if (c1.getClassLoader() != c2.getClassLoader())
 234             return false;
 235         return Objects.equals(c1.getPackageName(), c2.getPackageName());


 364             if (s != null) {
 365                 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
 366                 printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
 367             }
 368             printStackPropertiesSet = true;
 369         }
 370     }
 371 
 372     public static boolean printStackTraceWhenAccessFails() {
 373         ensurePrintStackPropertiesSet();
 374         return printStackWhenAccessFails;
 375     }
 376 
 377     public static boolean printStackTraceWhenAccessSucceeds() {
 378         ensurePrintStackPropertiesSet();
 379         return printStackWhenAccessSucceeds;
 380     }
 381 
 382     /**
 383      * Throws IllegalAccessException with the an exception message based on
 384      * the access that is denied. This method throws meaningful exception only
 385      * when {@link #verifyMemberAccess(Class, Class, Class, int)} returns false
 386      * for the same parameters.
 387      */
 388     public static void throwIllegalAccessException(Class<?> currentClass,
 389                                                     Class<?> memberClass,
 390                                                     Class<?> targetClass,
 391                                                     int modifiers)
 392         throws IllegalAccessException
 393     {
 394         String currentSuffix = "";
 395         String memberSuffix = "";
 396         Module m1 = currentClass.getModule();
 397         if (m1.isNamed())
 398             currentSuffix = " (in " + m1 + ")";
 399         Module m2 = memberClass.getModule();
 400         if (m2.isNamed())
 401             memberSuffix = " (in " + m2 + ")";
 402 
 403         String memberPackageName = memberClass.getPackageName();
 404 
 405         String msg = currentClass + currentSuffix + " cannot access ";
 406         if (m2.isExported(memberPackageName, m1)) {
 407 
 408             // module access okay so include the modifiers in the message
 409             msg += "a member of " + memberClass + memberSuffix +
 410                     " with modifiers \"" + Modifier.toString(modifiers) + "\"";


< prev index next >