< prev index next >

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

Print this page
rev 13806 : 8150782: findClass / accessClass throw unexpected exceptions


  82      * <p>
  83      * For any given caller class {@code C}, the lookup object returned by this call
  84      * has equivalent capabilities to any lookup object
  85      * supplied by the JVM to the bootstrap method of an
  86      * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
  87      * executing in the same caller class {@code C}.
  88      * @return a lookup object for the caller of this method, with private access
  89      */
  90     @CallerSensitive
  91     public static Lookup lookup() {
  92         return new Lookup(Reflection.getCallerClass());
  93     }
  94 
  95     /**
  96      * Returns a {@link Lookup lookup object} which is trusted minimally.
  97      * It can only be used to create method handles to
  98      * publicly accessible fields and methods.
  99      * <p>
 100      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
 101      * of this lookup object will be {@link java.lang.Object}.


 102      *
 103      * <p style="font-size:smaller;">
 104      * <em>Discussion:</em>
 105      * The lookup class can be changed to any other class {@code C} using an expression of the form
 106      * {@link Lookup#in publicLookup().in(C.class)}.
 107      * Since all classes have equal access to public names,
 108      * such a change would confer no new access rights.

 109      * A public lookup object is always subject to
 110      * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
 111      * Also, it cannot access
 112      * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
 113      * @return a lookup object which is trusted minimally
 114      */
 115     public static Lookup publicLookup() {
 116         return Lookup.PUBLIC_LOOKUP;
 117     }
 118 
 119     /**
 120      * Performs an unchecked "crack" of a
 121      * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
 122      * The result is as if the user had obtained a lookup object capable enough
 123      * to crack the target method handle, called
 124      * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
 125      * on the target to obtain its symbolic reference, and then called
 126      * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
 127      * to resolve the symbolic reference to a member.
 128      * <p>


 624 
 625         /**
 626          * Creates a lookup on the specified new lookup class.
 627          * The resulting object will report the specified
 628          * class as its own {@link #lookupClass lookupClass}.
 629          * <p>
 630          * However, the resulting {@code Lookup} object is guaranteed
 631          * to have no more access capabilities than the original.
 632          * In particular, access capabilities can be lost as follows:<ul>
 633          * <li>If the new lookup class differs from the old one,
 634          * protected members will not be accessible by virtue of inheritance.
 635          * (Protected members may continue to be accessible because of package sharing.)
 636          * <li>If the new lookup class is in a different package
 637          * than the old one, protected and default (package) members will not be accessible.
 638          * <li>If the new lookup class is not within the same package member
 639          * as the old one, private members will not be accessible.
 640          * <li>If the new lookup class is not accessible to the old lookup class,
 641          * then no members, not even public members, will be accessible.
 642          * (In all other cases, public members will continue to be accessible.)
 643          * </ul>





 644          *
 645          * @param requestedLookupClass the desired lookup class for the new lookup object
 646          * @return a lookup object which reports the desired lookup class
 647          * @throws NullPointerException if the argument is null
 648          */
 649         public Lookup in(Class<?> requestedLookupClass) {
 650             Objects.requireNonNull(requestedLookupClass);
 651             if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
 652                 return new Lookup(requestedLookupClass, ALL_MODES);
 653             if (requestedLookupClass == this.lookupClass)
 654                 return this;  // keep same capabilities
 655             int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
 656             if ((newModes & PACKAGE) != 0
 657                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
 658                 newModes &= ~(PACKAGE|PRIVATE);
 659             }
 660             // Allow nestmate lookups to be created without special privilege:
 661             if ((newModes & PRIVATE) != 0
 662                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
 663                 newModes &= ~PRIVATE;


 922          * @param refc the class or interface from which the method is accessed
 923          * @param type the type of the method, with the receiver argument omitted, and a void return type
 924          * @return the desired method handle
 925          * @throws NoSuchMethodException if the constructor does not exist
 926          * @throws IllegalAccessException if access checking fails
 927          *                                or if the method's variable arity modifier bit
 928          *                                is set and {@code asVarargsCollector} fails
 929          * @exception SecurityException if a security manager is present and it
 930          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 931          * @throws NullPointerException if any argument is null
 932          */
 933         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
 934             String name = "<init>";
 935             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
 936             return getDirectConstructor(refc, ctor);
 937         }
 938 
 939         /**
 940          * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
 941          * initializer of the class is not run.




 942          *
 943          * @param targetName the fully qualified name of the class to be looked up.
 944          * @return the requested class.
 945          * @exception SecurityException if a security manager is present and it
 946          *            <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 947          * @throws LinkageError if the linkage fails
 948          * @throws ClassNotFoundException if the class does not exist.
 949          * @throws IllegalAccessException if the class is not accessible, using the allowed access
 950          * modes.
 951          * @exception SecurityException if a security manager is present and it
 952          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 953          * @since 9
 954          */
 955         public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
 956             Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
 957             return accessClass(targetClass);
 958         }
 959 
 960         /**
 961          * Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
 962          * static initializer of the class is not run.



 963          *
 964          * @param targetClass the class to be access-checked
 965          *
 966          * @return the class that has been access-checked
 967          *
 968          * @throws IllegalAccessException if the class is not accessible from the lookup class, using the allowed access
 969          * modes.
 970          * @exception SecurityException if a security manager is present and it
 971          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 972          * @since 9
 973          */
 974         public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
 975             if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, allowedModes)) {
 976                 throw new MemberName(targetClass).makeAccessException("access violation", this);
 977             }
 978             checkSecurityManager(targetClass, null);
 979             return targetClass;
 980         }
 981 
 982         /**




  82      * <p>
  83      * For any given caller class {@code C}, the lookup object returned by this call
  84      * has equivalent capabilities to any lookup object
  85      * supplied by the JVM to the bootstrap method of an
  86      * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
  87      * executing in the same caller class {@code C}.
  88      * @return a lookup object for the caller of this method, with private access
  89      */
  90     @CallerSensitive
  91     public static Lookup lookup() {
  92         return new Lookup(Reflection.getCallerClass());
  93     }
  94 
  95     /**
  96      * Returns a {@link Lookup lookup object} which is trusted minimally.
  97      * It can only be used to create method handles to
  98      * publicly accessible fields and methods.
  99      * <p>
 100      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
 101      * of this lookup object will be {@link java.lang.Object}.
 102      * Consequently, the lookup context of this lookup object will be the bootstrap
 103      * class loader, which means it cannot find user classes.
 104      *
 105      * <p style="font-size:smaller;">
 106      * <em>Discussion:</em>
 107      * The lookup class can be changed to any other class {@code C} using an expression of the form
 108      * {@link Lookup#in publicLookup().in(C.class)}.
 109      * Since all classes have equal access to public names,
 110      * such a change would confer no new access rights,
 111      * but may change the lookup context by virtue of changing the class loader.
 112      * A public lookup object is always subject to
 113      * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
 114      * Also, it cannot access
 115      * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
 116      * @return a lookup object which is trusted minimally
 117      */
 118     public static Lookup publicLookup() {
 119         return Lookup.PUBLIC_LOOKUP;
 120     }
 121 
 122     /**
 123      * Performs an unchecked "crack" of a
 124      * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
 125      * The result is as if the user had obtained a lookup object capable enough
 126      * to crack the target method handle, called
 127      * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
 128      * on the target to obtain its symbolic reference, and then called
 129      * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
 130      * to resolve the symbolic reference to a member.
 131      * <p>


 627 
 628         /**
 629          * Creates a lookup on the specified new lookup class.
 630          * The resulting object will report the specified
 631          * class as its own {@link #lookupClass lookupClass}.
 632          * <p>
 633          * However, the resulting {@code Lookup} object is guaranteed
 634          * to have no more access capabilities than the original.
 635          * In particular, access capabilities can be lost as follows:<ul>
 636          * <li>If the new lookup class differs from the old one,
 637          * protected members will not be accessible by virtue of inheritance.
 638          * (Protected members may continue to be accessible because of package sharing.)
 639          * <li>If the new lookup class is in a different package
 640          * than the old one, protected and default (package) members will not be accessible.
 641          * <li>If the new lookup class is not within the same package member
 642          * as the old one, private members will not be accessible.
 643          * <li>If the new lookup class is not accessible to the old lookup class,
 644          * then no members, not even public members, will be accessible.
 645          * (In all other cases, public members will continue to be accessible.)
 646          * </ul>
 647          * <p>
 648          * The resulting lookup's capabilities for loading classes
 649          * (used during {@link #findClass} invocations)
 650          * are determined by the lookup class' loader,
 651          * which may change due to this operation.
 652          *
 653          * @param requestedLookupClass the desired lookup class for the new lookup object
 654          * @return a lookup object which reports the desired lookup class
 655          * @throws NullPointerException if the argument is null
 656          */
 657         public Lookup in(Class<?> requestedLookupClass) {
 658             Objects.requireNonNull(requestedLookupClass);
 659             if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
 660                 return new Lookup(requestedLookupClass, ALL_MODES);
 661             if (requestedLookupClass == this.lookupClass)
 662                 return this;  // keep same capabilities
 663             int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
 664             if ((newModes & PACKAGE) != 0
 665                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
 666                 newModes &= ~(PACKAGE|PRIVATE);
 667             }
 668             // Allow nestmate lookups to be created without special privilege:
 669             if ((newModes & PRIVATE) != 0
 670                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
 671                 newModes &= ~PRIVATE;


 930          * @param refc the class or interface from which the method is accessed
 931          * @param type the type of the method, with the receiver argument omitted, and a void return type
 932          * @return the desired method handle
 933          * @throws NoSuchMethodException if the constructor does not exist
 934          * @throws IllegalAccessException if access checking fails
 935          *                                or if the method's variable arity modifier bit
 936          *                                is set and {@code asVarargsCollector} fails
 937          * @exception SecurityException if a security manager is present and it
 938          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 939          * @throws NullPointerException if any argument is null
 940          */
 941         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
 942             String name = "<init>";
 943             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
 944             return getDirectConstructor(refc, ctor);
 945         }
 946 
 947         /**
 948          * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
 949          * initializer of the class is not run.
 950          * <p>
 951          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
 952          * loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
 953          * load the requested class, and then determines whether the class is accessible to this lookup object.
 954          *
 955          * @param targetName the fully qualified name of the class to be looked up.
 956          * @return the requested class.
 957          * @exception SecurityException if a security manager is present and it
 958          *            <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 959          * @throws LinkageError if the linkage fails
 960          * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
 961          * @throws IllegalAccessException if the class is not accessible, using the allowed access
 962          * modes.
 963          * @exception SecurityException if a security manager is present and it
 964          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 965          * @since 9
 966          */
 967         public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
 968             Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
 969             return accessClass(targetClass);
 970         }
 971 
 972         /**
 973          * Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
 974          * static initializer of the class is not run.
 975          * <p>
 976          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class} and the
 977          * {@linkplain #lookupModes() lookup modes}.
 978          *
 979          * @param targetClass the class to be access-checked
 980          *
 981          * @return the class that has been access-checked
 982          *
 983          * @throws IllegalAccessException if the class is not accessible from the lookup class, using the allowed access
 984          * modes.
 985          * @exception SecurityException if a security manager is present and it
 986          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
 987          * @since 9
 988          */
 989         public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
 990             if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, allowedModes)) {
 991                 throw new MemberName(targetClass).makeAccessException("access violation", this);
 992             }
 993             checkSecurityManager(targetClass, null);
 994             return targetClass;
 995         }
 996 
 997         /**


< prev index next >