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 jdk.internal.reflect;
27
28
29 import java.lang.reflect.*;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Objects;
33 import jdk.internal.HotSpotIntrinsicCandidate;
34 import jdk.internal.misc.VM;
35 import sun.security.action.GetPropertyAction;
36
37 /** Common utility routines used by both java.lang and
38 java.lang.reflect */
39
40 public class Reflection {
41
42 /** Used to filter out fields and methods from certain classes from public
43 view, where they are sensitive or they may contain VM-internal objects.
44 These Maps are updated very rarely. Rather than synchronize on
45 each access, we use copy-on-write */
46 private static volatile Map<Class<?>,String[]> fieldFilterMap;
47 private static volatile Map<Class<?>,String[]> methodFilterMap;
48
49 static {
50 Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
51 map.put(Reflection.class,
52 new String[] {"fieldFilterMap", "methodFilterMap"});
53 map.put(System.class, new String[] {"security"});
201 public static boolean verifyModuleAccess(Class<?> currentClass,
202 Class<?> memberClass) {
203 return verifyModuleAccess(currentClass.getModule(), memberClass);
204 }
205
206 public static boolean verifyModuleAccess(Module currentModule, Class<?> memberClass) {
207 Module memberModule = memberClass.getModule();
208
209 // module may be null during startup (initLevel 0)
210 if (currentModule == memberModule)
211 return true; // same module (named or unnamed)
212
213 // memberClass may be primitive or array class
214 Class<?> c = memberClass;
215 while (c.isArray()) {
216 c = c.getComponentType();
217 }
218 if (c.isPrimitive())
219 return true;
220
221 // check that memberModule exports the package to currentModule
222 return memberModule.isExported(c.getPackageName(), currentModule);
223 }
224
225 /**
226 * Returns true if two classes in the same package.
227 */
228 private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
229 if (c1.getClassLoader() != c2.getClassLoader())
230 return false;
231 while (c1.isArray())
232 c1 = c1.getComponentType();
233 while (c2.isArray())
234 c2 = c2.getComponentType();
235 return Objects.equals(c1.getPackageName(), c2.getPackageName());
236 }
237
238 static boolean isSubclassOf(Class<?> queryClass,
239 Class<?> ofClass)
240 {
241 while (queryClass != null) {
242 if (queryClass == ofClass) {
331 public static boolean isCallerSensitive(Method m) {
332 final ClassLoader loader = m.getDeclaringClass().getClassLoader();
333 if (VM.isSystemDomainLoader(loader) || isExtClassLoader(loader)) {
334 return m.isAnnotationPresent(CallerSensitive.class);
335 }
336 return false;
337 }
338
339 private static boolean isExtClassLoader(ClassLoader loader) {
340 ClassLoader cl = ClassLoader.getSystemClassLoader();
341 while (cl != null) {
342 if (cl.getParent() == null && cl == loader) {
343 return true;
344 }
345 cl = cl.getParent();
346 }
347 return false;
348 }
349
350
351 // true to print a stack trace when IAE is thrown
352 private static volatile boolean printStackWhenAccessFails;
353
354 // true if printStackWhenAccessFails has been initialized
355 private static volatile boolean printStackWhenAccessFailsSet;
356
357 private static void printStackTraceIfNeeded(Throwable e) {
358 if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) {
359 String s = GetPropertyAction.privilegedGetProperty(
360 "sun.reflect.debugModuleAccessChecks");
361 printStackWhenAccessFails =
362 (s != null && !s.equalsIgnoreCase("false"));
363 printStackWhenAccessFailsSet = true;
364 }
365 if (printStackWhenAccessFails) {
366 e.printStackTrace();
367 }
368 }
369
370 /**
371 * Throws IllegalAccessException with the an exception message based on
372 * the access that is denied.
373 */
374 private static void throwIllegalAccessException(Class<?> currentClass,
375 Class<?> memberClass,
376 Object target,
377 int modifiers)
378 throws IllegalAccessException
379 {
380 String currentSuffix = "";
381 String memberSuffix = "";
382 Module m1 = currentClass.getModule();
383 if (m1.isNamed())
384 currentSuffix = " (in " + m1 + ")";
385 Module m2 = memberClass.getModule();
386 if (m2.isNamed())
387 memberSuffix = " (in " + m2 + ")";
399 msg += "a member of " + memberClass + memberSuffix +
400 " with modifiers \"" + Modifier.toString(modifiers) + "\"";
401
402 } else {
403 // module access failed
404 msg += memberClass + memberSuffix+ " because "
405 + m2 + " does not export " + memberPackageName;
406 if (m2.isNamed()) msg += " to " + m1;
407 }
408
409 throwIllegalAccessException(msg);
410 }
411
412 /**
413 * Throws IllegalAccessException with the given exception message.
414 */
415 public static void throwIllegalAccessException(String msg)
416 throws IllegalAccessException
417 {
418 IllegalAccessException e = new IllegalAccessException(msg);
419 printStackTraceIfNeeded(e);
420 throw e;
421 }
422
423 /**
424 * Throws InaccessibleObjectException with the given exception message.
425 */
426 public static void throwInaccessibleObjectException(String msg) {
427 InaccessibleObjectException e = new InaccessibleObjectException(msg);
428 printStackTraceIfNeeded(e);
429 throw e;
430 }
431
432 }
|
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 jdk.internal.reflect;
27
28
29 import java.lang.reflect.*;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Objects;
33 import jdk.internal.HotSpotIntrinsicCandidate;
34 import jdk.internal.misc.SharedSecrets;
35 import jdk.internal.misc.VM;
36 import sun.security.action.GetPropertyAction;
37
38 /** Common utility routines used by both java.lang and
39 java.lang.reflect */
40
41 public class Reflection {
42
43 /** Used to filter out fields and methods from certain classes from public
44 view, where they are sensitive or they may contain VM-internal objects.
45 These Maps are updated very rarely. Rather than synchronize on
46 each access, we use copy-on-write */
47 private static volatile Map<Class<?>,String[]> fieldFilterMap;
48 private static volatile Map<Class<?>,String[]> methodFilterMap;
49
50 static {
51 Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
52 map.put(Reflection.class,
53 new String[] {"fieldFilterMap", "methodFilterMap"});
54 map.put(System.class, new String[] {"security"});
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 // memberClass may be primitive or array class
215 Class<?> c = memberClass;
216 while (c.isArray()) {
217 c = c.getComponentType();
218 }
219 if (c.isPrimitive())
220 return true;
221
222 String pkg = c.getPackageName();
223 boolean allowed = memberModule.isExported(pkg, currentModule);
224 if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
225 if (!SharedSecrets.getJavaLangReflectModuleAccess()
226 .isStaticallyExported(memberModule, pkg, currentModule)) {
227 String msg = currentModule + " allowed access to member of " + memberClass;
228 new Exception(msg).printStackTrace(System.err);
229 }
230 }
231 return allowed;
232 }
233
234 /**
235 * Returns true if two classes in the same package.
236 */
237 private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
238 if (c1.getClassLoader() != c2.getClassLoader())
239 return false;
240 while (c1.isArray())
241 c1 = c1.getComponentType();
242 while (c2.isArray())
243 c2 = c2.getComponentType();
244 return Objects.equals(c1.getPackageName(), c2.getPackageName());
245 }
246
247 static boolean isSubclassOf(Class<?> queryClass,
248 Class<?> ofClass)
249 {
250 while (queryClass != null) {
251 if (queryClass == ofClass) {
340 public static boolean isCallerSensitive(Method m) {
341 final ClassLoader loader = m.getDeclaringClass().getClassLoader();
342 if (VM.isSystemDomainLoader(loader) || isExtClassLoader(loader)) {
343 return m.isAnnotationPresent(CallerSensitive.class);
344 }
345 return false;
346 }
347
348 private static boolean isExtClassLoader(ClassLoader loader) {
349 ClassLoader cl = ClassLoader.getSystemClassLoader();
350 while (cl != null) {
351 if (cl.getParent() == null && cl == loader) {
352 return true;
353 }
354 cl = cl.getParent();
355 }
356 return false;
357 }
358
359
360 // true to print a stack trace when access fails
361 private static volatile boolean printStackWhenAccessFails;
362
363 // true to print a stack trace when access succeeds
364 private static volatile boolean printStackWhenAccessSucceeds;
365
366 // true if printStack* values are initialized
367 private static volatile boolean printStackPropertiesSet;
368
369 private static void ensurePrintStackPropertiesSet() {
370 if (!printStackPropertiesSet && VM.initLevel() >= 1) {
371 String s = GetPropertyAction.privilegedGetProperty(
372 "sun.reflect.debugModuleAccessChecks");
373 if (s != null) {
374 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
375 printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
376 }
377 printStackPropertiesSet = true;
378 }
379 }
380
381 public static void enableStackTraces() {
382 printStackWhenAccessFails = true;
383 printStackWhenAccessSucceeds = true;
384 printStackPropertiesSet = true;
385 }
386
387 public static boolean printStackTraceWhenAccessFails() {
388 ensurePrintStackPropertiesSet();
389 return printStackWhenAccessFails;
390 }
391
392 public static boolean printStackTraceWhenAccessSucceeds() {
393 ensurePrintStackPropertiesSet();
394 return printStackWhenAccessSucceeds;
395 }
396
397 /**
398 * Throws IllegalAccessException with the an exception message based on
399 * the access that is denied.
400 */
401 private static void throwIllegalAccessException(Class<?> currentClass,
402 Class<?> memberClass,
403 Object target,
404 int modifiers)
405 throws IllegalAccessException
406 {
407 String currentSuffix = "";
408 String memberSuffix = "";
409 Module m1 = currentClass.getModule();
410 if (m1.isNamed())
411 currentSuffix = " (in " + m1 + ")";
412 Module m2 = memberClass.getModule();
413 if (m2.isNamed())
414 memberSuffix = " (in " + m2 + ")";
426 msg += "a member of " + memberClass + memberSuffix +
427 " with modifiers \"" + Modifier.toString(modifiers) + "\"";
428
429 } else {
430 // module access failed
431 msg += memberClass + memberSuffix+ " because "
432 + m2 + " does not export " + memberPackageName;
433 if (m2.isNamed()) msg += " to " + m1;
434 }
435
436 throwIllegalAccessException(msg);
437 }
438
439 /**
440 * Throws IllegalAccessException with the given exception message.
441 */
442 public static void throwIllegalAccessException(String msg)
443 throws IllegalAccessException
444 {
445 IllegalAccessException e = new IllegalAccessException(msg);
446 ensurePrintStackPropertiesSet();
447 if (printStackWhenAccessFails) {
448 e.printStackTrace(System.err);
449 }
450 throw e;
451 }
452 }
|