8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 java.lang.invoke;
27
28 import jdk.internal.org.objectweb.asm.ClassWriter;
29 import jdk.internal.org.objectweb.asm.Opcodes;
30 import jdk.internal.reflect.CallerSensitive;
31 import jdk.internal.reflect.Reflection;
32 import jdk.internal.vm.annotation.ForceInline;
33 import sun.invoke.util.ValueConversions;
34 import sun.invoke.util.VerifyAccess;
35 import sun.invoke.util.Wrapper;
36 import sun.reflect.misc.ReflectUtil;
37 import sun.security.util.SecurityConstants;
38
39 import java.lang.invoke.LambdaForm.BasicType;
40 import java.lang.reflect.Constructor;
41 import java.lang.reflect.Field;
42 import java.lang.reflect.Member;
43 import java.lang.reflect.Method;
44 import java.lang.reflect.Modifier;
45 import java.lang.reflect.Module;
46 import java.lang.reflect.ReflectPermission;
47 import java.nio.ByteOrder;
48 import java.util.ArrayList;
49 import java.util.Arrays;
94 * Do not store it in place where untrusted code can access it.
95 * <p>
96 * This method is caller sensitive, which means that it may return different
97 * values to different callers.
98 * <p>
99 * For any given caller class {@code C}, the lookup object returned by this call
100 * has equivalent capabilities to any lookup object
101 * supplied by the JVM to the bootstrap method of an
102 * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
103 * executing in the same caller class {@code C}.
104 * @return a lookup object for the caller of this method, with private access
105 */
106 @CallerSensitive
107 @ForceInline // to ensure Reflection.getCallerClass optimization
108 public static Lookup lookup() {
109 return new Lookup(Reflection.getCallerClass());
110 }
111
112 /**
113 * Returns a {@link Lookup lookup object} which is trusted minimally.
114 * It can only be used to create method handles to public members in
115 * public classes in packages that are exported unconditionally.
116 * <p>
117 * For now, the {@linkplain Lookup#lookupClass lookup class} of this lookup
118 * object is in an unnamed module.
119 * Consequently, the lookup context of this lookup object will be the bootstrap
120 * class loader, which means it cannot find user classes.
121 *
122 * <p style="font-size:smaller;">
123 * <em>Discussion:</em>
124 * The lookup class can be changed to any other class {@code C} using an expression of the form
125 * {@link Lookup#in publicLookup().in(C.class)}.
126 * but may change the lookup context by virtue of changing the class loader.
127 * A public lookup object is always subject to
128 * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
129 * Also, it cannot access
130 * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
131 * @return a lookup object which is trusted minimally
132 */
133 public static Lookup publicLookup() {
134 // During VM startup then only classes in the java.base module can be
135 // loaded and linked. This is because java.base exports aren't setup until
136 // the module system is initialized, hence types in the unnamed module
137 // (or any named module) can't link to java/lang/Object.
138 if (!jdk.internal.misc.VM.isModuleSystemInited()) {
139 return new Lookup(Object.class, Lookup.PUBLIC);
140 } else {
141 return LookupHelper.PUBLIC_LOOKUP;
142 }
143 }
144
145 /**
146 * Returns a {@link Lookup lookup object} with full capabilities to emulate all
147 * supported bytecode behaviors, including <a href="MethodHandles.Lookup.html#privacc">
148 * private access</a>, on a target class.
149 * This method checks that a caller, specified as a {@code Lookup} object, is allowed to
150 * do <em>deep reflection</em> on the target class. If {@code m1} is the module containing
151 * the {@link Lookup#lookupClass() lookup class}, and {@code m2} is the module containing
152 * the target class, then this check ensures that
153 * <ul>
154 * <li>{@code m1} {@link Module#canRead reads} {@code m2}.</li>
155 * <li>{@code m2} {@link Module#isOpen(String,Module) opens} the package containing
156 * the target class to at least {@code m1}.</li>
157 * <li>The lookup has the {@link Lookup#MODULE MODULE} lookup mode.</li>
158 * </ul>
159 * <p>
160 * If there is a security manager, its {@code checkPermission} method is called to
161 * check {@code ReflectPermission("suppressAccessChecks")}.
162 * @apiNote The {@code MODULE} lookup mode serves to authenticate that the lookup object
163 * was created by code in the caller module (or derived from a lookup object originally
164 * created by the caller). A lookup object with the {@code MODULE} lookup mode can be
165 * shared with trusted parties without giving away {@code PRIVATE} and {@code PACKAGE}
166 * access to the caller.
167 * @param targetClass the target class
168 * @param lookup the caller lookup object
169 * @return a lookup object for the target class, with private access
170 * @throws IllegalArgumentException if {@code targetClass} is a primitve type or array class
171 * @throws NullPointerException if {@code targetClass} or {@code caller} is {@code null}
172 * @throws IllegalAccessException if the access check specified above fails
173 * @throws SecurityException if denied by the security manager
174 * @since 9
175 * @see Lookup#dropLookupMode
176 */
177 public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
178 SecurityManager sm = System.getSecurityManager();
179 if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
180 if (targetClass.isPrimitive())
181 throw new IllegalArgumentException(targetClass + " is a primitive class");
182 if (targetClass.isArray())
183 throw new IllegalArgumentException(targetClass + " is an array class");
184 Module targetModule = targetClass.getModule();
185 Module callerModule = lookup.lookupClass().getModule();
186 if (callerModule != targetModule && targetModule.isNamed()) {
187 if (!callerModule.canRead(targetModule))
188 throw new IllegalAccessException(callerModule + " does not read " + targetModule);
189 String pn = targetClass.getPackageName();
190 assert pn != null && pn.length() > 0 : "unnamed package cannot be in named module";
191 if (!targetModule.isOpen(pn, callerModule))
192 throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
193 }
194 if ((lookup.lookupModes() & Lookup.MODULE) == 0)
195 throw new IllegalAccessException("lookup does not have MODULE lookup mode");
196 return new Lookup(targetClass);
197 }
198
199 /**
200 * Performs an unchecked "crack" of a
201 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
202 * The result is as if the user had obtained a lookup object capable enough
203 * to crack the target method handle, called
204 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
205 * on the target to obtain its symbolic reference, and then called
206 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
207 * to resolve the symbolic reference to a member.
208 * <p>
209 * If there is a security manager, its {@code checkPermission} method
210 * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
584 * <em>Discussion:</em>
585 * For example, the caller-sensitive method
586 * {@link java.lang.Class#forName(String) Class.forName(x)}
587 * can return varying classes or throw varying exceptions,
588 * depending on the class loader of the class that calls it.
589 * A public lookup of {@code Class.forName} will fail, because
590 * there is no reasonable way to determine its bytecode behavior.
591 * <p style="font-size:smaller;">
592 * If an application caches method handles for broad sharing,
593 * it should use {@code publicLookup()} to create them.
594 * If there is a lookup of {@code Class.forName}, it will fail,
595 * and the application must take appropriate action in that case.
596 * It may be that a later lookup, perhaps during the invocation of a
597 * bootstrap method, can incorporate the specific identity
598 * of the caller, making the method accessible.
599 * <p style="font-size:smaller;">
600 * The function {@code MethodHandles.lookup} is caller sensitive
601 * so that there can be a secure foundation for lookups.
602 * Nearly all other methods in the JSR 292 API rely on lookup
603 * objects to check access requests.
604 */
605 public static final
606 class Lookup {
607 /** The class on behalf of whom the lookup is being performed. */
608 private final Class<?> lookupClass;
609
610 /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
611 private final int allowedModes;
612
613 /** A single-bit mask representing {@code public} access,
614 * which may contribute to the result of {@link #lookupModes lookupModes}.
615 * The value, {@code 0x01}, happens to be the same as the value of the
616 * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
617 */
618 public static final int PUBLIC = Modifier.PUBLIC;
619
620 /** A single-bit mask representing {@code private} access,
621 * which may contribute to the result of {@link #lookupModes lookupModes}.
622 * The value, {@code 0x02}, happens to be the same as the value of the
623 * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
630 * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
631 */
632 public static final int PROTECTED = Modifier.PROTECTED;
633
634 /** A single-bit mask representing {@code package} access (default access),
635 * which may contribute to the result of {@link #lookupModes lookupModes}.
636 * The value is {@code 0x08}, which does not correspond meaningfully to
637 * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
638 */
639 public static final int PACKAGE = Modifier.STATIC;
640
641 /** A single-bit mask representing {@code module} access (default access),
642 * which may contribute to the result of {@link #lookupModes lookupModes}.
643 * The value is {@code 0x10}, which does not correspond meaningfully to
644 * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
645 * In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup}
646 * with this lookup mode can access all public types in the module of the
647 * lookup class and public types in packages exported by other modules
648 * to the module of the lookup class.
649 * @since 9
650 */
651 public static final int MODULE = PACKAGE << 1;
652
653 private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE);
654 private static final int TRUSTED = -1;
655
656 private static int fixmods(int mods) {
657 mods &= (ALL_MODES - PACKAGE - MODULE);
658 return (mods != 0) ? mods : (PACKAGE | MODULE);
659 }
660
661 /** Tells which class is performing the lookup. It is this class against
662 * which checks are performed for visibility and access permissions.
663 * <p>
664 * The class implies a maximum level of access permission,
665 * but the permissions may be additionally limited by the bitmask
666 * {@link #lookupModes lookupModes}, which controls whether non-public members
667 * can be accessed.
668 * @return the lookup class, on behalf of which this lookup object finds members
669 */
670 public Class<?> lookupClass() {
671 return lookupClass;
672 }
673
674 // This is just for calling out to MethodHandleImpl.
675 private Class<?> lookupClassOrNull() {
676 return (allowedModes == TRUSTED) ? null : lookupClass;
677 }
678
679 /** Tells which access-protection classes of members this lookup object can produce.
680 * The result is a bit-mask of the bits
681 * {@linkplain #PUBLIC PUBLIC (0x01)},
682 * {@linkplain #PRIVATE PRIVATE (0x02)},
683 * {@linkplain #PROTECTED PROTECTED (0x04)},
684 * {@linkplain #PACKAGE PACKAGE (0x08)},
685 * and {@linkplain #MODULE MODULE (0x10)}.
686 * <p>
687 * A freshly-created lookup object
688 * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
689 * has all possible bits set, since the caller class can access all its own members,
690 * all public types in the caller's module, and all public types in packages exported
691 * by other modules to the caller's module.
692 * A lookup object on a new lookup class
693 * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
694 * may have some mode bits set to zero.
695 * Mode bits can also be
696 * {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}.
697 * Once cleared, mode bits cannot be restored from the downgraded lookup object.
698 * The purpose of this is to restrict access via the new lookup object,
699 * so that it can access only names which can be reached by the original
700 * lookup object, and also by the new lookup class.
701 * @return the lookup modes, which limit the kinds of access performed by this lookup object
702 * @see #in
703 * @see #dropLookupMode
704 */
705 public int lookupModes() {
706 return allowedModes & ALL_MODES;
707 }
708
709 /** Embody the current class (the lookupClass) as a lookup class
710 * for method handle creation.
711 * Must be called by from a method in this package,
712 * which in turn is called by a method not in this package.
713 */
714 Lookup(Class<?> lookupClass) {
715 this(lookupClass, ALL_MODES);
716 // make sure we haven't accidentally picked up a privileged class:
717 checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
718 }
719
720 private Lookup(Class<?> lookupClass, int allowedModes) {
721 this.lookupClass = lookupClass;
722 this.allowedModes = allowedModes;
723 }
724
725 /**
726 * Creates a lookup on the specified new lookup class.
727 * The resulting object will report the specified
728 * class as its own {@link #lookupClass lookupClass}.
729 * <p>
730 * However, the resulting {@code Lookup} object is guaranteed
731 * to have no more access capabilities than the original.
732 * In particular, access capabilities can be lost as follows:<ul>
733 * <li>If the lookup class for this {@code Lookup} is not in a named module,
734 * and the new lookup class is in a named module {@code M}, then no members in
735 * {@code M}'s non-exported packages will be accessible.
736 * <li>If the lookup for this {@code Lookup} is in a named module, and the
737 * new lookup class is in a different module {@code M}, then no members, not even
738 * public members in {@code M}'s exported packages, will be accessible.
739 * <li>If the new lookup class differs from the old one,
740 * protected members will not be accessible by virtue of inheritance.
741 * (Protected members may continue to be accessible because of package sharing.)
742 * <li>If the new lookup class is in a different package
743 * than the old one, protected and default (package) members will not be accessible.
744 * <li>If the new lookup class is not within the same package member
745 * as the old one, private members will not be accessible.
746 * <li>If the new lookup class is not accessible to the old lookup class,
747 * then no members, not even public members, will be accessible.
748 * (In all other cases, public members will continue to be accessible.)
749 * </ul>
750 * <p>
751 * The resulting lookup's capabilities for loading classes
752 * (used during {@link #findClass} invocations)
753 * are determined by the lookup class' loader,
754 * which may change due to this operation.
755 *
756 * @param requestedLookupClass the desired lookup class for the new lookup object
757 * @return a lookup object which reports the desired lookup class, or the same object
758 * if there is no change
759 * @throws NullPointerException if the argument is null
760 */
761 public Lookup in(Class<?> requestedLookupClass) {
762 Objects.requireNonNull(requestedLookupClass);
763 if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
764 return new Lookup(requestedLookupClass, ALL_MODES);
765 if (requestedLookupClass == this.lookupClass)
766 return this; // keep same capabilities
767
768 int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
769 if (!VerifyAccess.isSameModule(this.lookupClass, requestedLookupClass)) {
770 // Allowed to teleport from an unnamed to a named module but resulting
771 // Lookup has no access to module private members
772 if (this.lookupClass.getModule().isNamed()) {
773 newModes = 0;
774 } else {
775 newModes &= ~MODULE;
776 }
777 }
778 if ((newModes & PACKAGE) != 0
779 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
780 newModes &= ~(PACKAGE|PRIVATE);
781 }
782 // Allow nestmate lookups to be created without special privilege:
783 if ((newModes & PRIVATE) != 0
784 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
785 newModes &= ~PRIVATE;
786 }
787 if ((newModes & PUBLIC) != 0
788 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
789 // The requested class it not accessible from the lookup class.
790 // No permissions.
791 newModes = 0;
792 }
793
794 checkUnprivilegedlookupClass(requestedLookupClass, newModes);
795 return new Lookup(requestedLookupClass, newModes);
796 }
797
798
799 /**
800 * Creates a lookup on the same lookup class which this lookup object
801 * finds members, but with a lookup mode that has lost the given lookup mode.
802 * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
803 * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
804 * {@link #PROTECTED PROTECTED} is always dropped and so the resulting lookup
805 * mode will never have this access capability. When dropping {@code PACKAGE}
806 * then the resulting lookup will not have {@code PACKAGE} or {@code PRIVATE}
807 * access. When dropping {@code MODULE} then the resulting lookup will not
808 * have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code
809 * PUBLIC} is dropped then the resulting lookup has no access.
810 * @param modeToDrop the lookup mode to drop
811 * @return a lookup object which lacks the indicated mode, or the same object if there is no change
812 * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
813 * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED} or {@code PRIVATE}
814 * @since 9
815 * @see MethodHandles#privateLookupIn
816 */
817 public Lookup dropLookupMode(int modeToDrop) {
818 int oldModes = lookupModes();
819 int newModes = oldModes & ~(modeToDrop | PROTECTED);
820 switch (modeToDrop) {
821 case PUBLIC: newModes &= ~(ALL_MODES); break;
822 case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
823 case PACKAGE: newModes &= ~(PRIVATE); break;
824 case PROTECTED:
825 case PRIVATE: break;
826 default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
827 }
828 if (newModes == oldModes) return this; // return self if no change
829 return new Lookup(lookupClass(), newModes);
830 }
831
832 // Make sure outer class is initialized first.
833 static { IMPL_NAMES.getClass(); }
834
835 /** Package-private version of lookup which is trusted. */
836 static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
837
838 private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
839 String name = lookupClass.getName();
840 if (name.startsWith("java.lang.invoke."))
841 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
842
843 // For caller-sensitive MethodHandles.lookup() disallow lookup from
844 // restricted packages. This a fragile and blunt approach.
845 // TODO replace with a more formal and less fragile mechanism
846 // that does not bluntly restrict classes under packages within
847 // java.base from looking up MethodHandles or VarHandles.
848 if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
849 if ((name.startsWith("java.") &&
850 !name.equals("java.lang.Thread") &&
851 !name.startsWith("java.util.concurrent.")) ||
852 (name.startsWith("sun.") &&
853 !name.startsWith("sun.invoke."))) {
854 throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
855 }
856 }
857 }
858
859 /**
860 * Displays the name of the class from which lookups are to be made.
861 * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
862 * If there are restrictions on the access permitted to this lookup,
863 * this is indicated by adding a suffix to the class name, consisting
864 * of a slash and a keyword. The keyword represents the strongest
865 * allowed access, and is chosen as follows:
866 * <ul>
867 * <li>If no access is allowed, the suffix is "/noaccess".
868 * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
869 * <li>If only public and module access are allowed, the suffix is "/module".
870 * <li>If only public, module and package access are allowed, the suffix is "/package".
871 * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
872 * </ul>
873 * If none of the above cases apply, it is the case that full
874 * access (public, module, package, private, and protected) is allowed.
875 * In this case, no suffix is added.
876 * This is true only of an object obtained originally from
877 * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
878 * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
879 * always have restricted access, and will display a suffix.
880 * <p>
881 * (It may seem strange that protected access should be
882 * stronger than private access. Viewed independently from
883 * package access, protected access is the first to be lost,
884 * because it requires a direct subclass relationship between
885 * caller and callee.)
886 * @see #in
887 */
888 @Override
889 public String toString() {
890 String cname = lookupClass.getName();
891 switch (allowedModes) {
892 case 0: // no privileges
893 return cname + "/noaccess";
894 case PUBLIC:
895 return cname + "/public";
896 case PUBLIC|MODULE:
897 return cname + "/module";
898 case PUBLIC|MODULE|PACKAGE:
899 return cname + "/package";
900 case ALL_MODES & ~PROTECTED:
901 return cname + "/private";
902 case ALL_MODES:
903 return cname;
904 case TRUSTED:
905 return "/trusted"; // internal only; not exported
906 default: // Should not happen, but it's a bitfield...
907 cname = cname + "/" + Integer.toHexString(allowedModes);
908 assert(false) : cname;
909 return cname;
910 }
911 }
912
913 /**
914 * Produces a method handle for a static method.
915 * The type of the method handle will be that of the method.
916 * (Since static methods do not take receivers, there is no
917 * additional receiver argument inserted into the method handle type,
918 * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
919 * The method and all its argument types must be accessible to the lookup object.
920 * <p>
921 * The returned method handle will have
922 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1563 * @return a method handle which can invoke the reflected method
1564 * @throws IllegalAccessException if access checking fails
1565 * or if the method's variable arity modifier bit
1566 * is set and {@code asVarargsCollector} fails
1567 * @throws NullPointerException if the argument is null
1568 */
1569 public MethodHandle unreflect(Method m) throws IllegalAccessException {
1570 if (m.getDeclaringClass() == MethodHandle.class) {
1571 MethodHandle mh = unreflectForMH(m);
1572 if (mh != null) return mh;
1573 }
1574 if (m.getDeclaringClass() == VarHandle.class) {
1575 MethodHandle mh = unreflectForVH(m);
1576 if (mh != null) return mh;
1577 }
1578 MemberName method = new MemberName(m);
1579 byte refKind = method.getReferenceKind();
1580 if (refKind == REF_invokeSpecial)
1581 refKind = REF_invokeVirtual;
1582 assert(method.isMethod());
1583 Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
1584 return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
1585 }
1586 private MethodHandle unreflectForMH(Method m) {
1587 // these names require special lookups because they throw UnsupportedOperationException
1588 if (MemberName.isMethodHandleInvokeName(m.getName()))
1589 return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
1590 return null;
1591 }
1592 private MethodHandle unreflectForVH(Method m) {
1593 // these names require special lookups because they throw UnsupportedOperationException
1594 if (MemberName.isVarHandleMethodInvokeName(m.getName()))
1595 return MethodHandleImpl.fakeVarHandleInvoke(new MemberName(m));
1596 return null;
1597 }
1598
1599 /**
1600 * Produces a method handle for a reflected method.
1601 * It will bypass checks for overriding methods on the receiver,
1602 * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
1645 * <p>
1646 * If the constructor's {@code accessible} flag is not set,
1647 * access checking is performed immediately on behalf of the lookup class.
1648 * <p>
1649 * The returned method handle will have
1650 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1651 * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
1652 * <p>
1653 * If the returned method handle is invoked, the constructor's class will
1654 * be initialized, if it has not already been initialized.
1655 * @param c the reflected constructor
1656 * @return a method handle which can invoke the reflected constructor
1657 * @throws IllegalAccessException if access checking fails
1658 * or if the method's variable arity modifier bit
1659 * is set and {@code asVarargsCollector} fails
1660 * @throws NullPointerException if the argument is null
1661 */
1662 public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
1663 MemberName ctor = new MemberName(c);
1664 assert(ctor.isConstructor());
1665 Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
1666 return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
1667 }
1668
1669 /**
1670 * Produces a method handle giving read access to a reflected field.
1671 * The type of the method handle will have a return type of the field's
1672 * value type.
1673 * If the field is static, the method handle will take no arguments.
1674 * Otherwise, its single argument will be the instance containing
1675 * the field.
1676 * If the field's {@code accessible} flag is not set,
1677 * access checking is performed immediately on behalf of the lookup class.
1678 * <p>
1679 * If the field is static, and
1680 * if the returned method handle is invoked, the field's class will
1681 * be initialized, if it has not already been initialized.
1682 * @param f the reflected field
1683 * @return a method handle which can load values from the reflected field
1684 * @throws IllegalAccessException if access checking fails
1685 * @throws NullPointerException if the argument is null
1686 */
1687 public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1688 return unreflectField(f, false);
1689 }
1690 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
1691 MemberName field = new MemberName(f, isSetter);
1692 assert(isSetter
1693 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
1694 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
1695 Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
1696 return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
1697 }
1698
1699 /**
1700 * Produces a method handle giving write access to a reflected field.
1701 * The type of the method handle will have a void return type.
1702 * If the field is static, the method handle will take a single
1703 * argument, of the field's value type, the value to be stored.
1704 * Otherwise, the two arguments will be the instance containing
1705 * the field, and the value to be stored.
1706 * If the field's {@code accessible} flag is not set,
1707 * access checking is performed immediately on behalf of the lookup class.
1708 * <p>
1709 * If the field is static, and
1710 * if the returned method handle is invoked, the field's class will
1711 * be initialized, if it has not already been initialized.
1712 * @param f the reflected field
1713 * @return a method handle which can store values into the reflected field
1714 * @throws IllegalAccessException if access checking fails
2016 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
2017 mods, lookupClass(), allowedModes))
2018 return;
2019 } else {
2020 // Protected members can also be checked as if they were package-private.
2021 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
2022 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
2023 return;
2024 }
2025 throw m.makeAccessException(accessFailedMessage(refc, m), this);
2026 }
2027
2028 String accessFailedMessage(Class<?> refc, MemberName m) {
2029 Class<?> defc = m.getDeclaringClass();
2030 int mods = m.getModifiers();
2031 // check the class first:
2032 boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
2033 (defc == refc ||
2034 Modifier.isPublic(refc.getModifiers())));
2035 if (!classOK && (allowedModes & PACKAGE) != 0) {
2036 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
2037 (defc == refc ||
2038 VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
2039 }
2040 if (!classOK)
2041 return "class is not public";
2042 if (Modifier.isPublic(mods))
2043 return "access to public member failed"; // (how?, module not readable?)
2044 if (Modifier.isPrivate(mods))
2045 return "member is private";
2046 if (Modifier.isProtected(mods))
2047 return "member is protected";
2048 return "member is private to package";
2049 }
2050
2051 private static final boolean ALLOW_NESTMATE_ACCESS = false;
2052
2053 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
2054 int allowedModes = this.allowedModes;
2055 if (allowedModes == TRUSTED) return;
2056 if (!hasPrivateAccess()
2057 || (specialCaller != lookupClass()
2058 // ensure non-abstract methods in superinterfaces can be special-invoked
2331 return true;
2332 }
2333 private
2334 MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
2335 throws ReflectiveOperationException {
2336 if (MethodHandleNatives.refKindIsField(refKind)) {
2337 return getDirectFieldNoSecurityManager(refKind, defc, member);
2338 } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
2339 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
2340 } else if (refKind == REF_newInvokeSpecial) {
2341 return getDirectConstructorNoSecurityManager(defc, member);
2342 }
2343 // oops
2344 throw newIllegalArgumentException("bad MethodHandle constant #"+member);
2345 }
2346
2347 static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
2348 }
2349
2350 /**
2351 * Helper class used to lazily create PUBLIC_LOOKUP with a lookup class
2352 * in an <em>unnamed module</em>.
2353 *
2354 * @see Lookup#publicLookup
2355 */
2356 private static class LookupHelper {
2357 private static final String UNNAMED = "Unnamed";
2358 private static final String OBJECT = "java/lang/Object";
2359
2360 private static Class<?> createClass() {
2361 try {
2362 ClassWriter cw = new ClassWriter(0);
2363 cw.visit(Opcodes.V1_8,
2364 Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
2365 UNNAMED,
2366 null,
2367 OBJECT,
2368 null);
2369 cw.visitSource(UNNAMED, null);
2370 cw.visitEnd();
2371 byte[] bytes = cw.toByteArray();
2372 ClassLoader loader = new ClassLoader(null) {
2373 @Override
2374 protected Class<?> findClass(String cn) throws ClassNotFoundException {
2375 if (cn.equals(UNNAMED))
2376 return super.defineClass(UNNAMED, bytes, 0, bytes.length);
2377 throw new ClassNotFoundException(cn);
2378 }
2379 };
2380 return loader.loadClass(UNNAMED);
2381 } catch (Exception e) {
2382 throw new InternalError(e);
2383 }
2384 }
2385
2386 private static final Class<?> PUBLIC_LOOKUP_CLASS = createClass();
2387
2388 /**
2389 * Lookup that is trusted minimally. It can only be used to create
2390 * method handles to publicly accessible members in exported packages.
2391 *
2392 * @see MethodHandles#publicLookup
2393 */
2394 static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC);
2395 }
2396
2397 /**
2398 * Produces a method handle constructing arrays of a desired type.
2399 * The return type of the method handle will be the array type.
2400 * The type of its sole argument will be {@code int}, which specifies the size of the array.
2401 * @param arrayClass an array type
2402 * @return a method handle which can create arrays of the given type
2403 * @throws NullPointerException if the argument is {@code null}
2404 * @throws IllegalArgumentException if {@code arrayClass} is not an array type
2405 * @see java.lang.reflect.Array#newInstance(Class, int)
2406 * @since 9
2407 */
2408 public static
2409 MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
2410 if (!arrayClass.isArray()) {
2411 throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
2412 }
2413 MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
2414 bindTo(arrayClass.getComponentType());
2415 return ani.asType(ani.type().changeReturnType(arrayClass));
2416 }
2417
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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 java.lang.invoke;
27
28 import jdk.internal.reflect.CallerSensitive;
29 import jdk.internal.reflect.Reflection;
30 import jdk.internal.vm.annotation.ForceInline;
31 import sun.invoke.util.ValueConversions;
32 import sun.invoke.util.VerifyAccess;
33 import sun.invoke.util.Wrapper;
34 import sun.reflect.misc.ReflectUtil;
35 import sun.security.util.SecurityConstants;
36
37 import java.lang.invoke.LambdaForm.BasicType;
38 import java.lang.reflect.Constructor;
39 import java.lang.reflect.Field;
40 import java.lang.reflect.Member;
41 import java.lang.reflect.Method;
42 import java.lang.reflect.Modifier;
43 import java.lang.reflect.Module;
44 import java.lang.reflect.ReflectPermission;
45 import java.nio.ByteOrder;
46 import java.util.ArrayList;
47 import java.util.Arrays;
92 * Do not store it in place where untrusted code can access it.
93 * <p>
94 * This method is caller sensitive, which means that it may return different
95 * values to different callers.
96 * <p>
97 * For any given caller class {@code C}, the lookup object returned by this call
98 * has equivalent capabilities to any lookup object
99 * supplied by the JVM to the bootstrap method of an
100 * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
101 * executing in the same caller class {@code C}.
102 * @return a lookup object for the caller of this method, with private access
103 */
104 @CallerSensitive
105 @ForceInline // to ensure Reflection.getCallerClass optimization
106 public static Lookup lookup() {
107 return new Lookup(Reflection.getCallerClass());
108 }
109
110 /**
111 * Returns a {@link Lookup lookup object} which is trusted minimally.
112 * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
113 * It can only be used to create method handles to public members of
114 * public classes in packages that are exported unconditionally.
115 * <p>
116 * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
117 * of this lookup object will be {@link java.lang.Object}.
118 *
119 * @apiNote The use of Object is conventional, and because the lookup modes are
120 * limited, there is no special access provided to the internals of Object, its package
121 * or its module. Consequently, the lookup context of this lookup object will be the
122 * bootstrap class loader, which means it cannot find user classes.
123 *
124 * <p style="font-size:smaller;">
125 * <em>Discussion:</em>
126 * The lookup class can be changed to any other class {@code C} using an expression of the form
127 * {@link Lookup#in publicLookup().in(C.class)}.
128 * but may change the lookup context by virtue of changing the class loader.
129 * A public lookup object is always subject to
130 * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
131 * Also, it cannot access
132 * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
133 * @return a lookup object which is trusted minimally
134 *
135 * @revised 9
136 * @spec JPMS
137 */
138 public static Lookup publicLookup() {
139 return Lookup.PUBLIC_LOOKUP;
140 }
141
142 /**
143 * Returns a {@link Lookup lookup object} with full capabilities to emulate all
144 * supported bytecode behaviors, including <a href="MethodHandles.Lookup.html#privacc">
145 * private access</a>, on a target class.
146 * This method checks that a caller, specified as a {@code Lookup} object, is allowed to
147 * do <em>deep reflection</em> on the target class. If {@code m1} is the module containing
148 * the {@link Lookup#lookupClass() lookup class}, and {@code m2} is the module containing
149 * the target class, then this check ensures that
150 * <ul>
151 * <li>{@code m1} {@link Module#canRead reads} {@code m2}.</li>
152 * <li>{@code m2} {@link Module#isOpen(String,Module) opens} the package containing
153 * the target class to at least {@code m1}.</li>
154 * <li>The lookup has the {@link Lookup#MODULE MODULE} lookup mode.</li>
155 * </ul>
156 * <p>
157 * If there is a security manager, its {@code checkPermission} method is called to
158 * check {@code ReflectPermission("suppressAccessChecks")}.
159 * @apiNote The {@code MODULE} lookup mode serves to authenticate that the lookup object
160 * was created by code in the caller module (or derived from a lookup object originally
161 * created by the caller). A lookup object with the {@code MODULE} lookup mode can be
162 * shared with trusted parties without giving away {@code PRIVATE} and {@code PACKAGE}
163 * access to the caller.
164 * @param targetClass the target class
165 * @param lookup the caller lookup object
166 * @return a lookup object for the target class, with private access
167 * @throws IllegalArgumentException if {@code targetClass} is a primitve type or array class
168 * @throws NullPointerException if {@code targetClass} or {@code caller} is {@code null}
169 * @throws IllegalAccessException if the access check specified above fails
170 * @throws SecurityException if denied by the security manager
171 * @since 9
172 * @spec JPMS
173 * @see Lookup#dropLookupMode
174 */
175 public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
176 SecurityManager sm = System.getSecurityManager();
177 if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
178 if (targetClass.isPrimitive())
179 throw new IllegalArgumentException(targetClass + " is a primitive class");
180 if (targetClass.isArray())
181 throw new IllegalArgumentException(targetClass + " is an array class");
182 Module targetModule = targetClass.getModule();
183 Module callerModule = lookup.lookupClass().getModule();
184 if (!callerModule.canRead(targetModule))
185 throw new IllegalAccessException(callerModule + " does not read " + targetModule);
186 if (targetModule.isNamed()) {
187 String pn = targetClass.getPackageName();
188 assert pn.length() > 0 : "unnamed package cannot be in named module";
189 if (!targetModule.isOpen(pn, callerModule))
190 throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
191 }
192 if ((lookup.lookupModes() & Lookup.MODULE) == 0)
193 throw new IllegalAccessException("lookup does not have MODULE lookup mode");
194 return new Lookup(targetClass);
195 }
196
197 /**
198 * Performs an unchecked "crack" of a
199 * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
200 * The result is as if the user had obtained a lookup object capable enough
201 * to crack the target method handle, called
202 * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
203 * on the target to obtain its symbolic reference, and then called
204 * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
205 * to resolve the symbolic reference to a member.
206 * <p>
207 * If there is a security manager, its {@code checkPermission} method
208 * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
582 * <em>Discussion:</em>
583 * For example, the caller-sensitive method
584 * {@link java.lang.Class#forName(String) Class.forName(x)}
585 * can return varying classes or throw varying exceptions,
586 * depending on the class loader of the class that calls it.
587 * A public lookup of {@code Class.forName} will fail, because
588 * there is no reasonable way to determine its bytecode behavior.
589 * <p style="font-size:smaller;">
590 * If an application caches method handles for broad sharing,
591 * it should use {@code publicLookup()} to create them.
592 * If there is a lookup of {@code Class.forName}, it will fail,
593 * and the application must take appropriate action in that case.
594 * It may be that a later lookup, perhaps during the invocation of a
595 * bootstrap method, can incorporate the specific identity
596 * of the caller, making the method accessible.
597 * <p style="font-size:smaller;">
598 * The function {@code MethodHandles.lookup} is caller sensitive
599 * so that there can be a secure foundation for lookups.
600 * Nearly all other methods in the JSR 292 API rely on lookup
601 * objects to check access requests.
602 *
603 * @revised 9
604 */
605 public static final
606 class Lookup {
607 /** The class on behalf of whom the lookup is being performed. */
608 private final Class<?> lookupClass;
609
610 /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
611 private final int allowedModes;
612
613 /** A single-bit mask representing {@code public} access,
614 * which may contribute to the result of {@link #lookupModes lookupModes}.
615 * The value, {@code 0x01}, happens to be the same as the value of the
616 * {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
617 */
618 public static final int PUBLIC = Modifier.PUBLIC;
619
620 /** A single-bit mask representing {@code private} access,
621 * which may contribute to the result of {@link #lookupModes lookupModes}.
622 * The value, {@code 0x02}, happens to be the same as the value of the
623 * {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
630 * {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
631 */
632 public static final int PROTECTED = Modifier.PROTECTED;
633
634 /** A single-bit mask representing {@code package} access (default access),
635 * which may contribute to the result of {@link #lookupModes lookupModes}.
636 * The value is {@code 0x08}, which does not correspond meaningfully to
637 * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
638 */
639 public static final int PACKAGE = Modifier.STATIC;
640
641 /** A single-bit mask representing {@code module} access (default access),
642 * which may contribute to the result of {@link #lookupModes lookupModes}.
643 * The value is {@code 0x10}, which does not correspond meaningfully to
644 * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
645 * In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup}
646 * with this lookup mode can access all public types in the module of the
647 * lookup class and public types in packages exported by other modules
648 * to the module of the lookup class.
649 * @since 9
650 * @spec JPMS
651 */
652 public static final int MODULE = PACKAGE << 1;
653
654 /** A single-bit mask representing {@code unconditional} access
655 * which may contribute to the result of {@link #lookupModes lookupModes}.
656 * The value is {@code 0x20}, which does not correspond meaningfully to
657 * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
658 * A {@code Lookup} with this lookup mode assumes {@linkplain
659 * java.lang.reflect.Module#canRead(java.lang.reflect.Module) readability}.
660 * In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup}
661 * with this lookup mode can access all public members of public types
662 * of all modules where the type is in a package that is {@link
663 * java.lang.reflect.Module#isExported(String) exported unconditionally}.
664 * @see #publicLookup()
665 * @since 9
666 */
667 public static final int UNCONDITIONAL = PACKAGE << 2;
668
669 private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE | UNCONDITIONAL);
670 private static final int FULL_POWER_MODES = (ALL_MODES & ~UNCONDITIONAL);
671 private static final int TRUSTED = -1;
672
673 private static int fixmods(int mods) {
674 mods &= (ALL_MODES - PACKAGE - MODULE - UNCONDITIONAL);
675 return (mods != 0) ? mods : (PACKAGE | MODULE | UNCONDITIONAL);
676 }
677
678 /** Tells which class is performing the lookup. It is this class against
679 * which checks are performed for visibility and access permissions.
680 * <p>
681 * The class implies a maximum level of access permission,
682 * but the permissions may be additionally limited by the bitmask
683 * {@link #lookupModes lookupModes}, which controls whether non-public members
684 * can be accessed.
685 * @return the lookup class, on behalf of which this lookup object finds members
686 */
687 public Class<?> lookupClass() {
688 return lookupClass;
689 }
690
691 // This is just for calling out to MethodHandleImpl.
692 private Class<?> lookupClassOrNull() {
693 return (allowedModes == TRUSTED) ? null : lookupClass;
694 }
695
696 /** Tells which access-protection classes of members this lookup object can produce.
697 * The result is a bit-mask of the bits
698 * {@linkplain #PUBLIC PUBLIC (0x01)},
699 * {@linkplain #PRIVATE PRIVATE (0x02)},
700 * {@linkplain #PROTECTED PROTECTED (0x04)},
701 * {@linkplain #PACKAGE PACKAGE (0x08)},
702 * {@linkplain #MODULE MODULE (0x10)},
703 * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}.
704 * <p>
705 * A freshly-created lookup object
706 * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has
707 * all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to
708 * access all members of the caller's class, all public types in the caller's module,
709 * and all public types in packages exported by other modules to the caller's module.
710 * A lookup object on a new lookup class
711 * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
712 * may have some mode bits set to zero.
713 * Mode bits can also be
714 * {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}.
715 * Once cleared, mode bits cannot be restored from the downgraded lookup object.
716 * The purpose of this is to restrict access via the new lookup object,
717 * so that it can access only names which can be reached by the original
718 * lookup object, and also by the new lookup class.
719 * @return the lookup modes, which limit the kinds of access performed by this lookup object
720 * @see #in
721 * @see #dropLookupMode
722 *
723 * @revised 9
724 * @spec JPMS
725 */
726 public int lookupModes() {
727 return allowedModes & ALL_MODES;
728 }
729
730 /** Embody the current class (the lookupClass) as a lookup class
731 * for method handle creation.
732 * Must be called by from a method in this package,
733 * which in turn is called by a method not in this package.
734 */
735 Lookup(Class<?> lookupClass) {
736 this(lookupClass, FULL_POWER_MODES);
737 // make sure we haven't accidentally picked up a privileged class:
738 checkUnprivilegedlookupClass(lookupClass, FULL_POWER_MODES);
739 }
740
741 private Lookup(Class<?> lookupClass, int allowedModes) {
742 this.lookupClass = lookupClass;
743 this.allowedModes = allowedModes;
744 }
745
746 /**
747 * Creates a lookup on the specified new lookup class.
748 * The resulting object will report the specified
749 * class as its own {@link #lookupClass lookupClass}.
750 * <p>
751 * However, the resulting {@code Lookup} object is guaranteed
752 * to have no more access capabilities than the original.
753 * In particular, access capabilities can be lost as follows:<ul>
754 * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
755 * the new lookup class is in a different module {@code M}, then no members, not
756 * even public members in {@code M}'s exported packages, will be accessible.
757 * The exception to this is when this lookup is {@link #publicLookup()
758 * publicLookup}, in which case {@code PUBLIC} access is not lost.
759 * <li>If the old lookup class is in an unnamed module, and the new lookup class
760 * is a different module then {@link #MODULE MODULE} access is lost.
761 * <li>If the new lookup class differs from the old one then {@code UNCONDITIONAL} is lost.
762 * <li>If the new lookup class is in a different package
763 * than the old one, protected and default (package) members will not be accessible.
764 * <li>If the new lookup class is not within the same package member
765 * as the old one, private members will not be accessible, and protected members
766 * will not be accessible by virtue of inheritance.
767 * (Protected members may continue to be accessible because of package sharing.)
768 * <li>If the new lookup class is not accessible to the old lookup class,
769 * then no members, not even public members, will be accessible.
770 * (In all other cases, public members will continue to be accessible.)
771 * </ul>
772 * <p>
773 * The resulting lookup's capabilities for loading classes
774 * (used during {@link #findClass} invocations)
775 * are determined by the lookup class' loader,
776 * which may change due to this operation.
777 *
778 * @param requestedLookupClass the desired lookup class for the new lookup object
779 * @return a lookup object which reports the desired lookup class, or the same object
780 * if there is no change
781 * @throws NullPointerException if the argument is null
782 *
783 * @revised 9
784 * @spec JPMS
785 */
786 public Lookup in(Class<?> requestedLookupClass) {
787 Objects.requireNonNull(requestedLookupClass);
788 if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
789 return new Lookup(requestedLookupClass, FULL_POWER_MODES);
790 if (requestedLookupClass == this.lookupClass)
791 return this; // keep same capabilities
792 int newModes = (allowedModes & FULL_POWER_MODES);
793 if (!VerifyAccess.isSameModule(this.lookupClass, requestedLookupClass)) {
794 // Need to drop all access when teleporting from a named module to another
795 // module. The exception is publicLookup where PUBLIC is not lost.
796 if (this.lookupClass.getModule().isNamed()
797 && (this.allowedModes & UNCONDITIONAL) == 0)
798 newModes = 0;
799 else
800 newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
801 }
802 if ((newModes & PACKAGE) != 0
803 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
804 newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
805 }
806 // Allow nestmate lookups to be created without special privilege:
807 if ((newModes & PRIVATE) != 0
808 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
809 newModes &= ~(PRIVATE|PROTECTED);
810 }
811 if ((newModes & PUBLIC) != 0
812 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
813 // The requested class it not accessible from the lookup class.
814 // No permissions.
815 newModes = 0;
816 }
817
818 checkUnprivilegedlookupClass(requestedLookupClass, newModes);
819 return new Lookup(requestedLookupClass, newModes);
820 }
821
822
823 /**
824 * Creates a lookup on the same lookup class which this lookup object
825 * finds members, but with a lookup mode that has lost the given lookup mode.
826 * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
827 * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
828 * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
829 * dropped and so the resulting lookup mode will never have these access capabilities.
830 * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
831 * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
832 * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
833 * is dropped then the resulting lookup has no access.
834 * @param modeToDrop the lookup mode to drop
835 * @return a lookup object which lacks the indicated mode, or the same object if there is no change
836 * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
837 * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
838 * @see MethodHandles#privateLookupIn
839 * @since 9
840 */
841 public Lookup dropLookupMode(int modeToDrop) {
842 int oldModes = lookupModes();
843 int newModes = oldModes & ~(modeToDrop | PROTECTED | UNCONDITIONAL);
844 switch (modeToDrop) {
845 case PUBLIC: newModes &= ~(ALL_MODES); break;
846 case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
847 case PACKAGE: newModes &= ~(PRIVATE); break;
848 case PROTECTED:
849 case PRIVATE:
850 case UNCONDITIONAL: break;
851 default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
852 }
853 if (newModes == oldModes) return this; // return self if no change
854 return new Lookup(lookupClass(), newModes);
855 }
856
857 // Make sure outer class is initialized first.
858 static { IMPL_NAMES.getClass(); }
859
860 /** Package-private version of lookup which is trusted. */
861 static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
862
863 /** Version of lookup which is trusted minimally.
864 * It can only be used to create method handles to publicly accessible
865 * members in packages that are exported unconditionally.
866 */
867 static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
868
869 private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
870 String name = lookupClass.getName();
871 if (name.startsWith("java.lang.invoke."))
872 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
873
874 // For caller-sensitive MethodHandles.lookup() disallow lookup from
875 // restricted packages. This a fragile and blunt approach.
876 // TODO replace with a more formal and less fragile mechanism
877 // that does not bluntly restrict classes under packages within
878 // java.base from looking up MethodHandles or VarHandles.
879 if (allowedModes == FULL_POWER_MODES && lookupClass.getClassLoader() == null) {
880 if ((name.startsWith("java.") &&
881 !name.equals("java.lang.Thread") &&
882 !name.startsWith("java.util.concurrent.")) ||
883 (name.startsWith("sun.") &&
884 !name.startsWith("sun.invoke."))) {
885 throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
886 }
887 }
888 }
889
890 /**
891 * Displays the name of the class from which lookups are to be made.
892 * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
893 * If there are restrictions on the access permitted to this lookup,
894 * this is indicated by adding a suffix to the class name, consisting
895 * of a slash and a keyword. The keyword represents the strongest
896 * allowed access, and is chosen as follows:
897 * <ul>
898 * <li>If no access is allowed, the suffix is "/noaccess".
899 * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
900 * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
901 * <li>If only public and module access are allowed, the suffix is "/module".
902 * <li>If only public, module and package access are allowed, the suffix is "/package".
903 * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
904 * </ul>
905 * If none of the above cases apply, it is the case that full
906 * access (public, module, package, private, and protected) is allowed.
907 * In this case, no suffix is added.
908 * This is true only of an object obtained originally from
909 * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
910 * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
911 * always have restricted access, and will display a suffix.
912 * <p>
913 * (It may seem strange that protected access should be
914 * stronger than private access. Viewed independently from
915 * package access, protected access is the first to be lost,
916 * because it requires a direct subclass relationship between
917 * caller and callee.)
918 * @see #in
919 *
920 * @revised 9
921 * @spec JPMS
922 */
923 @Override
924 public String toString() {
925 String cname = lookupClass.getName();
926 switch (allowedModes) {
927 case 0: // no privileges
928 return cname + "/noaccess";
929 case PUBLIC:
930 return cname + "/public";
931 case PUBLIC|UNCONDITIONAL:
932 return cname + "/publicLookup";
933 case PUBLIC|MODULE:
934 return cname + "/module";
935 case PUBLIC|MODULE|PACKAGE:
936 return cname + "/package";
937 case FULL_POWER_MODES & ~PROTECTED:
938 return cname + "/private";
939 case FULL_POWER_MODES:
940 return cname;
941 case TRUSTED:
942 return "/trusted"; // internal only; not exported
943 default: // Should not happen, but it's a bitfield...
944 cname = cname + "/" + Integer.toHexString(allowedModes);
945 assert(false) : cname;
946 return cname;
947 }
948 }
949
950 /**
951 * Produces a method handle for a static method.
952 * The type of the method handle will be that of the method.
953 * (Since static methods do not take receivers, there is no
954 * additional receiver argument inserted into the method handle type,
955 * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
956 * The method and all its argument types must be accessible to the lookup object.
957 * <p>
958 * The returned method handle will have
959 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1600 * @return a method handle which can invoke the reflected method
1601 * @throws IllegalAccessException if access checking fails
1602 * or if the method's variable arity modifier bit
1603 * is set and {@code asVarargsCollector} fails
1604 * @throws NullPointerException if the argument is null
1605 */
1606 public MethodHandle unreflect(Method m) throws IllegalAccessException {
1607 if (m.getDeclaringClass() == MethodHandle.class) {
1608 MethodHandle mh = unreflectForMH(m);
1609 if (mh != null) return mh;
1610 }
1611 if (m.getDeclaringClass() == VarHandle.class) {
1612 MethodHandle mh = unreflectForVH(m);
1613 if (mh != null) return mh;
1614 }
1615 MemberName method = new MemberName(m);
1616 byte refKind = method.getReferenceKind();
1617 if (refKind == REF_invokeSpecial)
1618 refKind = REF_invokeVirtual;
1619 assert(method.isMethod());
1620 @SuppressWarnings("deprecation")
1621 Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
1622 return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
1623 }
1624 private MethodHandle unreflectForMH(Method m) {
1625 // these names require special lookups because they throw UnsupportedOperationException
1626 if (MemberName.isMethodHandleInvokeName(m.getName()))
1627 return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
1628 return null;
1629 }
1630 private MethodHandle unreflectForVH(Method m) {
1631 // these names require special lookups because they throw UnsupportedOperationException
1632 if (MemberName.isVarHandleMethodInvokeName(m.getName()))
1633 return MethodHandleImpl.fakeVarHandleInvoke(new MemberName(m));
1634 return null;
1635 }
1636
1637 /**
1638 * Produces a method handle for a reflected method.
1639 * It will bypass checks for overriding methods on the receiver,
1640 * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
1683 * <p>
1684 * If the constructor's {@code accessible} flag is not set,
1685 * access checking is performed immediately on behalf of the lookup class.
1686 * <p>
1687 * The returned method handle will have
1688 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1689 * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
1690 * <p>
1691 * If the returned method handle is invoked, the constructor's class will
1692 * be initialized, if it has not already been initialized.
1693 * @param c the reflected constructor
1694 * @return a method handle which can invoke the reflected constructor
1695 * @throws IllegalAccessException if access checking fails
1696 * or if the method's variable arity modifier bit
1697 * is set and {@code asVarargsCollector} fails
1698 * @throws NullPointerException if the argument is null
1699 */
1700 public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
1701 MemberName ctor = new MemberName(c);
1702 assert(ctor.isConstructor());
1703 @SuppressWarnings("deprecation")
1704 Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
1705 return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
1706 }
1707
1708 /**
1709 * Produces a method handle giving read access to a reflected field.
1710 * The type of the method handle will have a return type of the field's
1711 * value type.
1712 * If the field is static, the method handle will take no arguments.
1713 * Otherwise, its single argument will be the instance containing
1714 * the field.
1715 * If the field's {@code accessible} flag is not set,
1716 * access checking is performed immediately on behalf of the lookup class.
1717 * <p>
1718 * If the field is static, and
1719 * if the returned method handle is invoked, the field's class will
1720 * be initialized, if it has not already been initialized.
1721 * @param f the reflected field
1722 * @return a method handle which can load values from the reflected field
1723 * @throws IllegalAccessException if access checking fails
1724 * @throws NullPointerException if the argument is null
1725 */
1726 public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1727 return unreflectField(f, false);
1728 }
1729 private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
1730 MemberName field = new MemberName(f, isSetter);
1731 assert(isSetter
1732 ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
1733 : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
1734 @SuppressWarnings("deprecation")
1735 Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
1736 return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
1737 }
1738
1739 /**
1740 * Produces a method handle giving write access to a reflected field.
1741 * The type of the method handle will have a void return type.
1742 * If the field is static, the method handle will take a single
1743 * argument, of the field's value type, the value to be stored.
1744 * Otherwise, the two arguments will be the instance containing
1745 * the field, and the value to be stored.
1746 * If the field's {@code accessible} flag is not set,
1747 * access checking is performed immediately on behalf of the lookup class.
1748 * <p>
1749 * If the field is static, and
1750 * if the returned method handle is invoked, the field's class will
1751 * be initialized, if it has not already been initialized.
1752 * @param f the reflected field
1753 * @return a method handle which can store values into the reflected field
1754 * @throws IllegalAccessException if access checking fails
2056 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
2057 mods, lookupClass(), allowedModes))
2058 return;
2059 } else {
2060 // Protected members can also be checked as if they were package-private.
2061 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
2062 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
2063 return;
2064 }
2065 throw m.makeAccessException(accessFailedMessage(refc, m), this);
2066 }
2067
2068 String accessFailedMessage(Class<?> refc, MemberName m) {
2069 Class<?> defc = m.getDeclaringClass();
2070 int mods = m.getModifiers();
2071 // check the class first:
2072 boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
2073 (defc == refc ||
2074 Modifier.isPublic(refc.getModifiers())));
2075 if (!classOK && (allowedModes & PACKAGE) != 0) {
2076 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), FULL_POWER_MODES) &&
2077 (defc == refc ||
2078 VerifyAccess.isClassAccessible(refc, lookupClass(), FULL_POWER_MODES)));
2079 }
2080 if (!classOK)
2081 return "class is not public";
2082 if (Modifier.isPublic(mods))
2083 return "access to public member failed"; // (how?, module not readable?)
2084 if (Modifier.isPrivate(mods))
2085 return "member is private";
2086 if (Modifier.isProtected(mods))
2087 return "member is protected";
2088 return "member is private to package";
2089 }
2090
2091 private static final boolean ALLOW_NESTMATE_ACCESS = false;
2092
2093 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
2094 int allowedModes = this.allowedModes;
2095 if (allowedModes == TRUSTED) return;
2096 if (!hasPrivateAccess()
2097 || (specialCaller != lookupClass()
2098 // ensure non-abstract methods in superinterfaces can be special-invoked
2371 return true;
2372 }
2373 private
2374 MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
2375 throws ReflectiveOperationException {
2376 if (MethodHandleNatives.refKindIsField(refKind)) {
2377 return getDirectFieldNoSecurityManager(refKind, defc, member);
2378 } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
2379 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
2380 } else if (refKind == REF_newInvokeSpecial) {
2381 return getDirectConstructorNoSecurityManager(defc, member);
2382 }
2383 // oops
2384 throw newIllegalArgumentException("bad MethodHandle constant #"+member);
2385 }
2386
2387 static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
2388 }
2389
2390 /**
2391 * Produces a method handle constructing arrays of a desired type.
2392 * The return type of the method handle will be the array type.
2393 * The type of its sole argument will be {@code int}, which specifies the size of the array.
2394 * @param arrayClass an array type
2395 * @return a method handle which can create arrays of the given type
2396 * @throws NullPointerException if the argument is {@code null}
2397 * @throws IllegalArgumentException if {@code arrayClass} is not an array type
2398 * @see java.lang.reflect.Array#newInstance(Class, int)
2399 * @since 9
2400 */
2401 public static
2402 MethodHandle arrayConstructor(Class<?> arrayClass) throws IllegalArgumentException {
2403 if (!arrayClass.isArray()) {
2404 throw newIllegalArgumentException("not an array class: " + arrayClass.getName());
2405 }
2406 MethodHandle ani = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_Array_newInstance).
2407 bindTo(arrayClass.getComponentType());
2408 return ani.asType(ani.type().changeReturnType(arrayClass));
2409 }
2410
|