< prev index next >

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

Print this page




  96      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
  97      * Do not store it in place where untrusted code can access it.
  98      * <p>
  99      * This method is caller sensitive, which means that it may return different
 100      * values to different callers.
 101      * <p>
 102      * For any given caller class {@code C}, the lookup object returned by this call
 103      * has equivalent capabilities to any lookup object
 104      * supplied by the JVM to the bootstrap method of an
 105      * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
 106      * executing in the same caller class {@code C}.
 107      * @return a lookup object for the caller of this method, with private access
 108      */
 109     @CallerSensitive
 110     @ForceInline // to ensure Reflection.getCallerClass optimization
 111     public static Lookup lookup() {
 112         return new Lookup(Reflection.getCallerClass());
 113     }
 114 
 115     /**













 116      * Returns a {@link Lookup lookup object} which is trusted minimally.
 117      * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
 118      * It can only be used to create method handles to public members of
 119      * public classes in packages that are exported unconditionally.
 120      * <p>
 121      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
 122      * of this lookup object will be {@link java.lang.Object}.
 123      *
 124      * @apiNote The use of Object is conventional, and because the lookup modes are
 125      * limited, there is no special access provided to the internals of Object, its package
 126      * or its module. Consequently, the lookup context of this lookup object will be the
 127      * bootstrap class loader, which means it cannot find user classes.
 128      *
 129      * <p style="font-size:smaller;">
 130      * <em>Discussion:</em>
 131      * The lookup class can be changed to any other class {@code C} using an expression of the form
 132      * {@link Lookup#in publicLookup().in(C.class)}.
 133      * but may change the lookup context by virtue of changing the class loader.
 134      * A public lookup object is always subject to
 135      * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.


 730          *  lookup object, and also by the new lookup class.
 731          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
 732          *  @see #in
 733          *  @see #dropLookupMode
 734          *
 735          *  @revised 9
 736          *  @spec JPMS
 737          */
 738         public int lookupModes() {
 739             return allowedModes & ALL_MODES;
 740         }
 741 
 742         /** Embody the current class (the lookupClass) as a lookup class
 743          * for method handle creation.
 744          * Must be called by from a method in this package,
 745          * which in turn is called by a method not in this package.
 746          */
 747         Lookup(Class<?> lookupClass) {
 748             this(lookupClass, FULL_POWER_MODES);
 749             // make sure we haven't accidentally picked up a privileged class:
 750             checkUnprivilegedlookupClass(lookupClass, FULL_POWER_MODES);
 751         }
 752 
 753         private Lookup(Class<?> lookupClass, int allowedModes) {
 754             this.lookupClass = lookupClass;
 755             this.allowedModes = allowedModes;
 756         }
 757 
 758         /**
 759          * Creates a lookup on the specified new lookup class.
 760          * The resulting object will report the specified
 761          * class as its own {@link #lookupClass lookupClass}.
 762          * <p>
 763          * However, the resulting {@code Lookup} object is guaranteed
 764          * to have no more access capabilities than the original.
 765          * In particular, access capabilities can be lost as follows:<ul>
 766          * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
 767          * the new lookup class is in a different module {@code M}, then no members, not
 768          * even public members in {@code M}'s exported packages, will be accessible.
 769          * The exception to this is when this lookup is {@link #publicLookup()
 770          * publicLookup}, in which case {@code PUBLIC} access is not lost.


 810                     newModes = 0;
 811                 else
 812                     newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
 813             }
 814             if ((newModes & PACKAGE) != 0
 815                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
 816                 newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
 817             }
 818             // Allow nestmate lookups to be created without special privilege:
 819             if ((newModes & PRIVATE) != 0
 820                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
 821                 newModes &= ~(PRIVATE|PROTECTED);
 822             }
 823             if ((newModes & PUBLIC) != 0
 824                 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
 825                 // The requested class it not accessible from the lookup class.
 826                 // No permissions.
 827                 newModes = 0;
 828             }
 829 
 830             checkUnprivilegedlookupClass(requestedLookupClass, newModes);
 831             return new Lookup(requestedLookupClass, newModes);
 832         }
 833 
 834 
 835         /**
 836          * Creates a lookup on the same lookup class which this lookup object
 837          * finds members, but with a lookup mode that has lost the given lookup mode.
 838          * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
 839          * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
 840          * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
 841          * dropped and so the resulting lookup mode will never have these access capabilities.
 842          * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
 843          * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
 844          * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
 845          * is dropped then the resulting lookup has no access.
 846          * @param modeToDrop the lookup mode to drop
 847          * @return a lookup object which lacks the indicated mode, or the same object if there is no change
 848          * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
 849          * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
 850          * @see MethodHandles#privateLookupIn


 967             PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
 968             return AccessController.doPrivileged(pa);
 969         }
 970 
 971         // cached protection domain
 972         private volatile ProtectionDomain cachedProtectionDomain;
 973 
 974 
 975         // Make sure outer class is initialized first.
 976         static { IMPL_NAMES.getClass(); }
 977 
 978         /** Package-private version of lookup which is trusted. */
 979         static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
 980 
 981         /** Version of lookup which is trusted minimally.
 982          *  It can only be used to create method handles to publicly accessible
 983          *  members in packages that are exported unconditionally.
 984          */
 985         static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
 986 
 987         private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
 988             String name = lookupClass.getName();
 989             if (name.startsWith("java.lang.invoke."))
 990                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
 991 
 992             // For caller-sensitive MethodHandles.lookup() disallow lookup from
 993             // restricted packages.  This a fragile and blunt approach.
 994             // TODO replace with a more formal and less fragile mechanism
 995             // that does not bluntly restrict classes under packages within
 996             // java.base from looking up MethodHandles or VarHandles.
 997             if (allowedModes == FULL_POWER_MODES && lookupClass.getClassLoader() == null) {
 998                 if ((name.startsWith("java.") &&
 999                      !name.equals("java.lang.Thread") &&
1000                      !name.startsWith("java.util.concurrent.")) ||
1001                     (name.startsWith("sun.") &&
1002                      !name.startsWith("sun.invoke."))) {
1003                     throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
1004                 }
1005             }
1006         }
1007 
1008         /**
1009          * Displays the name of the class from which lookups are to be made.
1010          * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
1011          * If there are restrictions on the access permitted to this lookup,
1012          * this is indicated by adding a suffix to the class name, consisting
1013          * of a slash and a keyword.  The keyword represents the strongest
1014          * allowed access, and is chosen as follows:
1015          * <ul>
1016          * <li>If no access is allowed, the suffix is "/noaccess".
1017          * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
1018          * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
1019          * <li>If only public and module access are allowed, the suffix is "/module".
1020          * <li>If only public, module and package access are allowed, the suffix is "/package".
1021          * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
1022          * </ul>
1023          * If none of the above cases apply, it is the case that full
1024          * access (public, module, package, private, and protected) is allowed.
1025          * In this case, no suffix is added.




  96      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
  97      * Do not store it in place where untrusted code can access it.
  98      * <p>
  99      * This method is caller sensitive, which means that it may return different
 100      * values to different callers.
 101      * <p>
 102      * For any given caller class {@code C}, the lookup object returned by this call
 103      * has equivalent capabilities to any lookup object
 104      * supplied by the JVM to the bootstrap method of an
 105      * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
 106      * executing in the same caller class {@code C}.
 107      * @return a lookup object for the caller of this method, with private access
 108      */
 109     @CallerSensitive
 110     @ForceInline // to ensure Reflection.getCallerClass optimization
 111     public static Lookup lookup() {
 112         return new Lookup(Reflection.getCallerClass());
 113     }
 114 
 115     /**
 116      * This reflected$lookup method is the alternate implementation of
 117      * the lookup method when being invoked by reflection.
 118      */
 119     @CallerSensitive
 120     private static Lookup reflected$lookup() {
 121         Class<?> caller = Reflection.getCallerClass();
 122         if (caller.getClassLoader() == null) {
 123             throw newIllegalArgumentException("illegal lookupClass: "+caller);
 124         }
 125         return new Lookup(caller);
 126     }
 127 
 128     /**
 129      * Returns a {@link Lookup lookup object} which is trusted minimally.
 130      * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
 131      * It can only be used to create method handles to public members of
 132      * public classes in packages that are exported unconditionally.
 133      * <p>
 134      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
 135      * of this lookup object will be {@link java.lang.Object}.
 136      *
 137      * @apiNote The use of Object is conventional, and because the lookup modes are
 138      * limited, there is no special access provided to the internals of Object, its package
 139      * or its module. Consequently, the lookup context of this lookup object will be the
 140      * bootstrap class loader, which means it cannot find user classes.
 141      *
 142      * <p style="font-size:smaller;">
 143      * <em>Discussion:</em>
 144      * The lookup class can be changed to any other class {@code C} using an expression of the form
 145      * {@link Lookup#in publicLookup().in(C.class)}.
 146      * but may change the lookup context by virtue of changing the class loader.
 147      * A public lookup object is always subject to
 148      * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.


 743          *  lookup object, and also by the new lookup class.
 744          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
 745          *  @see #in
 746          *  @see #dropLookupMode
 747          *
 748          *  @revised 9
 749          *  @spec JPMS
 750          */
 751         public int lookupModes() {
 752             return allowedModes & ALL_MODES;
 753         }
 754 
 755         /** Embody the current class (the lookupClass) as a lookup class
 756          * for method handle creation.
 757          * Must be called by from a method in this package,
 758          * which in turn is called by a method not in this package.
 759          */
 760         Lookup(Class<?> lookupClass) {
 761             this(lookupClass, FULL_POWER_MODES);
 762             // make sure we haven't accidentally picked up a privileged class:
 763             checkUnprivilegedlookupClass(lookupClass);
 764         }
 765 
 766         private Lookup(Class<?> lookupClass, int allowedModes) {
 767             this.lookupClass = lookupClass;
 768             this.allowedModes = allowedModes;
 769         }
 770 
 771         /**
 772          * Creates a lookup on the specified new lookup class.
 773          * The resulting object will report the specified
 774          * class as its own {@link #lookupClass lookupClass}.
 775          * <p>
 776          * However, the resulting {@code Lookup} object is guaranteed
 777          * to have no more access capabilities than the original.
 778          * In particular, access capabilities can be lost as follows:<ul>
 779          * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
 780          * the new lookup class is in a different module {@code M}, then no members, not
 781          * even public members in {@code M}'s exported packages, will be accessible.
 782          * The exception to this is when this lookup is {@link #publicLookup()
 783          * publicLookup}, in which case {@code PUBLIC} access is not lost.


 823                     newModes = 0;
 824                 else
 825                     newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
 826             }
 827             if ((newModes & PACKAGE) != 0
 828                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
 829                 newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
 830             }
 831             // Allow nestmate lookups to be created without special privilege:
 832             if ((newModes & PRIVATE) != 0
 833                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
 834                 newModes &= ~(PRIVATE|PROTECTED);
 835             }
 836             if ((newModes & PUBLIC) != 0
 837                 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
 838                 // The requested class it not accessible from the lookup class.
 839                 // No permissions.
 840                 newModes = 0;
 841             }
 842 
 843             checkUnprivilegedlookupClass(requestedLookupClass);
 844             return new Lookup(requestedLookupClass, newModes);
 845         }
 846 
 847 
 848         /**
 849          * Creates a lookup on the same lookup class which this lookup object
 850          * finds members, but with a lookup mode that has lost the given lookup mode.
 851          * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
 852          * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
 853          * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
 854          * dropped and so the resulting lookup mode will never have these access capabilities.
 855          * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
 856          * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
 857          * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
 858          * is dropped then the resulting lookup has no access.
 859          * @param modeToDrop the lookup mode to drop
 860          * @return a lookup object which lacks the indicated mode, or the same object if there is no change
 861          * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
 862          * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
 863          * @see MethodHandles#privateLookupIn


 980             PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
 981             return AccessController.doPrivileged(pa);
 982         }
 983 
 984         // cached protection domain
 985         private volatile ProtectionDomain cachedProtectionDomain;
 986 
 987 
 988         // Make sure outer class is initialized first.
 989         static { IMPL_NAMES.getClass(); }
 990 
 991         /** Package-private version of lookup which is trusted. */
 992         static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
 993 
 994         /** Version of lookup which is trusted minimally.
 995          *  It can only be used to create method handles to publicly accessible
 996          *  members in packages that are exported unconditionally.
 997          */
 998         static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
 999 
1000         private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
1001             String name = lookupClass.getName();
1002             if (name.startsWith("java.lang.invoke."))
1003                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);















1004         }
1005 
1006         /**
1007          * Displays the name of the class from which lookups are to be made.
1008          * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
1009          * If there are restrictions on the access permitted to this lookup,
1010          * this is indicated by adding a suffix to the class name, consisting
1011          * of a slash and a keyword.  The keyword represents the strongest
1012          * allowed access, and is chosen as follows:
1013          * <ul>
1014          * <li>If no access is allowed, the suffix is "/noaccess".
1015          * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
1016          * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
1017          * <li>If only public and module access are allowed, the suffix is "/module".
1018          * <li>If only public, module and package access are allowed, the suffix is "/package".
1019          * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
1020          * </ul>
1021          * If none of the above cases apply, it is the case that full
1022          * access (public, module, package, private, and protected) is allowed.
1023          * In this case, no suffix is added.


< prev index next >