< prev index next >

src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Print this page
rev 49429 : 8200289: Reduce number of exceptions created when calling Lookup::canBeCached
Reviewed-by: sundar, psandoz


2018                                             NoSuchFieldException.class);
2019         }
2020 
2021         MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2022             checkSymbolicClass(refc);  // do this before attempting to resolve
2023             Objects.requireNonNull(name);
2024             Objects.requireNonNull(type);
2025             checkMethodName(refKind, name);  // NPE check on name
2026             return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
2027                                             NoSuchMethodException.class);
2028         }
2029 
2030         MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException {
2031             checkSymbolicClass(member.getDeclaringClass());  // do this before attempting to resolve
2032             Objects.requireNonNull(member.getName());
2033             Objects.requireNonNull(member.getType());
2034             return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(),
2035                                             ReflectiveOperationException.class);
2036         }
2037 










2038         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {






2039             Objects.requireNonNull(refc);
2040             Class<?> caller = lookupClassOrNull();
2041             if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes))
2042                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
2043         }
2044 
2045         /** Check name for an illegal leading "&lt;" character. */
2046         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
2047             if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
2048                 throw new NoSuchMethodException("illegal method name: "+name);
2049         }
2050 
2051 
2052         /**
2053          * Find my trustable caller class if m is a caller sensitive method.
2054          * If this lookup object has private access, then the caller class is the lookupClass.
2055          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
2056          */
2057         Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
2058             Class<?> callerClass = null;
2059             if (MethodHandleNatives.isCallerSensitive(m)) {
2060                 // Only lookups with private access are allowed to resolve caller-sensitive methods
2061                 if (hasPrivateAccess()) {
2062                     callerClass = lookupClass;


2465             }
2466             if (!Modifier.isPublic(defc.getModifiers()) ||
2467                     !Modifier.isPublic(member.getDeclaringClass().getModifiers()) ||
2468                     !member.isPublic() ||
2469                     member.isCallerSensitive()) {
2470                 return false;
2471             }
2472             ClassLoader loader = defc.getClassLoader();
2473             if (loader != null) {
2474                 ClassLoader sysl = ClassLoader.getSystemClassLoader();
2475                 boolean found = false;
2476                 while (sysl != null) {
2477                     if (loader == sysl) { found = true; break; }
2478                     sysl = sysl.getParent();
2479                 }
2480                 if (!found) {
2481                     return false;
2482                 }
2483             }
2484             try {
2485                 MemberName resolved2 = publicLookup().resolveOrFail(refKind,
2486                     new MemberName(refKind, defc, member.getName(), member.getType()));



2487                 checkSecurityManager(defc, resolved2);
2488             } catch (ReflectiveOperationException | SecurityException ex) {
2489                 return false;
2490             }
2491             return true;
2492         }
2493         private
2494         MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
2495                 throws ReflectiveOperationException {
2496             if (MethodHandleNatives.refKindIsField(refKind)) {
2497                 return getDirectFieldNoSecurityManager(refKind, defc, member);
2498             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
2499                 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
2500             } else if (refKind == REF_newInvokeSpecial) {
2501                 return getDirectConstructorNoSecurityManager(defc, member);
2502             }
2503             // oops
2504             throw newIllegalArgumentException("bad MethodHandle constant #"+member);
2505         }
2506 
2507         static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
2508     }




2018                                             NoSuchFieldException.class);
2019         }
2020 
2021         MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2022             checkSymbolicClass(refc);  // do this before attempting to resolve
2023             Objects.requireNonNull(name);
2024             Objects.requireNonNull(type);
2025             checkMethodName(refKind, name);  // NPE check on name
2026             return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
2027                                             NoSuchMethodException.class);
2028         }
2029 
2030         MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException {
2031             checkSymbolicClass(member.getDeclaringClass());  // do this before attempting to resolve
2032             Objects.requireNonNull(member.getName());
2033             Objects.requireNonNull(member.getType());
2034             return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(),
2035                                             ReflectiveOperationException.class);
2036         }
2037 
2038         MemberName resolveOrNull(byte refKind, MemberName member) {
2039             // do this before attempting to resolve
2040             if (!isClassAccessible(member.getDeclaringClass())) {
2041                 return null;
2042             }
2043             Objects.requireNonNull(member.getName());
2044             Objects.requireNonNull(member.getType());
2045             return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull());
2046         }
2047 
2048         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
2049             if (!isClassAccessible(refc)) {
2050                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
2051             }
2052         }
2053 
2054         boolean isClassAccessible(Class<?> refc) {
2055             Objects.requireNonNull(refc);
2056             Class<?> caller = lookupClassOrNull();
2057             return caller == null || VerifyAccess.isClassAccessible(refc, caller, allowedModes);

2058         }
2059 
2060         /** Check name for an illegal leading "&lt;" character. */
2061         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
2062             if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
2063                 throw new NoSuchMethodException("illegal method name: "+name);
2064         }
2065 
2066 
2067         /**
2068          * Find my trustable caller class if m is a caller sensitive method.
2069          * If this lookup object has private access, then the caller class is the lookupClass.
2070          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
2071          */
2072         Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
2073             Class<?> callerClass = null;
2074             if (MethodHandleNatives.isCallerSensitive(m)) {
2075                 // Only lookups with private access are allowed to resolve caller-sensitive methods
2076                 if (hasPrivateAccess()) {
2077                     callerClass = lookupClass;


2480             }
2481             if (!Modifier.isPublic(defc.getModifiers()) ||
2482                     !Modifier.isPublic(member.getDeclaringClass().getModifiers()) ||
2483                     !member.isPublic() ||
2484                     member.isCallerSensitive()) {
2485                 return false;
2486             }
2487             ClassLoader loader = defc.getClassLoader();
2488             if (loader != null) {
2489                 ClassLoader sysl = ClassLoader.getSystemClassLoader();
2490                 boolean found = false;
2491                 while (sysl != null) {
2492                     if (loader == sysl) { found = true; break; }
2493                     sysl = sysl.getParent();
2494                 }
2495                 if (!found) {
2496                     return false;
2497                 }
2498             }
2499             try {
2500                 MemberName resolved2 = publicLookup().resolveOrNull(refKind,
2501                     new MemberName(refKind, defc, member.getName(), member.getType()));
2502                 if (resolved2 == null) {
2503                     return false;
2504                 }
2505                 checkSecurityManager(defc, resolved2);
2506             } catch (SecurityException ex) {
2507                 return false;
2508             }
2509             return true;
2510         }
2511         private
2512         MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
2513                 throws ReflectiveOperationException {
2514             if (MethodHandleNatives.refKindIsField(refKind)) {
2515                 return getDirectFieldNoSecurityManager(refKind, defc, member);
2516             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
2517                 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
2518             } else if (refKind == REF_newInvokeSpecial) {
2519                 return getDirectConstructorNoSecurityManager(defc, member);
2520             }
2521             // oops
2522             throw newIllegalArgumentException("bad MethodHandle constant #"+member);
2523         }
2524 
2525         static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
2526     }


< prev index next >