< prev index next >

src/java.base/share/classes/java/lang/reflect/Proxy.java

Print this page




 147  * the same manner as interface method invocations are encoded and
 148  * dispatched, as described above.  The declaring class of the
 149  * {@code Method} object passed to {@code invoke} will be
 150  * {@code java.lang.Object}.  Other public methods of a proxy
 151  * instance inherited from {@code java.lang.Object} are not
 152  * overridden by a proxy class, so invocations of those methods behave
 153  * like they do for instances of {@code java.lang.Object}.
 154  * </ul>
 155  *
 156  * <h3><a name="membership">Package and Module Membership of Proxy Class</a></h3>
 157  *
 158  * The package and module to which a proxy class belongs are chosen such that
 159  * the accessibility of the proxy class is in line with the accessibility of
 160  * the proxy interfaces. Specifically, the package and the module membership
 161  * of a proxy class defined via the
 162  * {@link Proxy#getProxyClass(ClassLoader, Class[])} or
 163  * {@link Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)}
 164  * methods is specified as follows:
 165  *
 166  * <ol>
 167  * <li>If all the proxy interfaces are in <em>exported</em> packages:

 168  * <ol type="a">
 169  * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
 170  *     <em>public</em> in a package exported by the
 171  *     {@linkplain ClassLoader#getUnnamedModule() unnamed module} of the specified
 172  *     loader. The name of the package is unspecified.</li>
 173  *
 174  * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then
 175  *     the proxy class is <em>non-public</em> in the package and module of the
 176  *     non-public interfaces. All the non-public interfaces must be in the same
 177  *     package and module; otherwise, proxying them is
 178  *     <a href="#restrictions">not possible</a>.</li>
 179  * </ol>
 180  * </li>
 181  * <li>If at least one proxy interface is a <em>non-exported</em> package:

 182  * <ol type="a">
 183  * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
 184  *     <em>public</em> in a <em>non-exported</em> package of
 185  *     <a href="#dynamicmodule"><em>dynamic module</em>.</a>
 186  *     The names of the package and the module are unspecified.</li>
 187  *
 188  * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then
 189  *     the proxy class is <em>non-public</em> in the package and module of the
 190  *     non-public interfaces. All the non-public interfaces must be in the same
 191  *     package and module; otherwise, proxying them is
 192  *     <a href="#restrictions">not possible</a>.</li>
 193  * </ol>
 194  * </li>
 195  * </ol>
 196  *
 197  * <p>
 198  * Note that if proxy interfaces with a mix of accessibilities --
 199  * exported public, exported non-public, non-exported public, non-exported non-public --
 200  * are proxied by the same instance, then the proxy class's accessibility is
 201  * governed by the least accessible proxy interface.
 202  * <p>
 203  * Note that it is possible for arbitrary code to obtain access to a proxy class
 204  * in an exported package with {@link AccessibleObject#setAccessible setAccessible},
 205  * whereas a proxy class in a non-exported package is never accessible to
 206  * code outside the module of the proxy class.
 207  *
 208  * <p>
 209  * Throughout this specification, a "non-exported package" refers to a package that
 210  * is not exported to all modules. Specifically, it refers to a package that
 211  * either is not exported at all by its containing module or is exported in a
 212  * qualified fashion by its containing module.

 213  *
 214  * <h3><a name="dynamicmodule">Dynamic Modules</a></h3>
 215  * <p>
 216  * A dynamic module is a named module generated at runtime. A proxy class
 217  * defined in a dynamic module is encapsulated and not accessible to any module.
 218  * Calling {@link Constructor#newInstance(Object...)} on a proxy class in
 219  * a dynamic module will throw {@code IllegalAccessException};
 220  * {@code Proxy.newProxyInstance} method should be used instead.
 221  *
 222  * <p>
 223  * A dynamic module can read the modules of all of the superinterfaces of a proxy class
 224  * and the modules of the types referenced by all public method signatures
 225  * of a proxy class.  If a superinterface or a referenced type, say {@code T},
 226  * is in a non-exported package, the {@linkplain java.lang.reflect.Module module}
 227  * of {@code T} is updated to export the package of {@code T} to the dynamic module.
 228  *
 229  * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
 230  *
 231  * <p>When two or more proxy interfaces contain a method with
 232  * the same name and parameter signature, the order of the proxy class's


 255  * which {@code Method} object to pass to the invocation handler.
 256  *
 257  * <p>Note also that when a duplicate method is dispatched to an
 258  * invocation handler, the {@code invoke} method may only throw
 259  * checked exception types that are assignable to one of the exception
 260  * types in the {@code throws} clause of the method in <i>all</i> of
 261  * the proxy interfaces that it can be invoked through.  If the
 262  * {@code invoke} method throws a checked exception that is not
 263  * assignable to any of the exception types declared by the method in one
 264  * of the proxy interfaces that it can be invoked through, then an
 265  * unchecked {@code UndeclaredThrowableException} will be thrown by
 266  * the invocation on the proxy instance.  This restriction means that not
 267  * all of the exception types returned by invoking
 268  * {@code getExceptionTypes} on the {@code Method} object
 269  * passed to the {@code invoke} method can necessarily be thrown
 270  * successfully by the {@code invoke} method.
 271  *
 272  * @author      Peter Jones
 273  * @see         InvocationHandler
 274  * @since       1.3


 275  */
 276 public class Proxy implements java.io.Serializable {
 277     private static final long serialVersionUID = -2222568056686623797L;
 278 
 279     /** parameter types of a proxy class constructor */
 280     private static final Class<?>[] constructorParams =
 281         { InvocationHandler.class };
 282 
 283     /**
 284      * a cache of proxy constructors with
 285      * {@link Constructor#setAccessible(boolean) accessible} flag already set
 286      */
 287     private static final ClassLoaderValue<Constructor<?>> proxyCache =
 288         new ClassLoaderValue<>();
 289 
 290     /**
 291      * the invocation handler for this proxy instance.
 292      * @serial
 293      */
 294     protected InvocationHandler h;


 341      *             s.checkPermission} with
 342      *             {@code RuntimePermission("getClassLoader")} permission
 343      *             denies access.</li>
 344      *             <li> for each proxy interface, {@code intf},
 345      *             the caller's class loader is not the same as or an
 346      *             ancestor of the class loader for {@code intf} and
 347      *             invocation of {@link SecurityManager#checkPackageAccess
 348      *             s.checkPackageAccess()} denies access to {@code intf}.</li>
 349      *          </ul>
 350      * @throws  NullPointerException if the {@code interfaces} array
 351      *          argument or any of its elements are {@code null}
 352      *
 353      * @deprecated Proxy classes generated in a named module are encapsulated and not
 354      *      accessible to code outside its module.
 355      *      {@link Constructor#newInstance(Object...) Constructor.newInstance} will throw
 356      *      {@code IllegalAccessException} when it is called on an inaccessible proxy class.
 357      *      Use {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)}
 358      *      to create a proxy instance instead.
 359      *
 360      * @see <a href="#membership">Package and Module Membership of Proxy Class</a>


 361      */
 362     @Deprecated
 363     @CallerSensitive
 364     public static Class<?> getProxyClass(ClassLoader loader,
 365                                          Class<?>... interfaces)
 366         throws IllegalArgumentException
 367     {
 368         Class<?> caller = System.getSecurityManager() == null
 369                               ? null
 370                               : Reflection.getCallerClass();
 371 
 372         return getProxyConstructor(caller, loader, interfaces)
 373             .getDeclaringClass();
 374     }
 375 
 376     /**
 377      * Returns the {@code Constructor} object of a proxy class that takes a
 378      * single argument of type {@link InvocationHandler}, given a class loader
 379      * and an array of interfaces. The returned constructor will have the
 380      * {@link Constructor#setAccessible(boolean) accessible} flag already set.


 938      *               {@code RuntimePermission("getClassLoader")} permission
 939      *               denies access;</li>
 940      *          <li> for each proxy interface, {@code intf},
 941      *               the caller's class loader is not the same as or an
 942      *               ancestor of the class loader for {@code intf} and
 943      *               invocation of {@link SecurityManager#checkPackageAccess
 944      *               s.checkPackageAccess()} denies access to {@code intf};</li>
 945      *          <li> any of the given proxy interfaces is non-public and the
 946      *               caller class is not in the same {@linkplain Package runtime package}
 947      *               as the non-public interface and the invocation of
 948      *               {@link SecurityManager#checkPermission s.checkPermission} with
 949      *               {@code ReflectPermission("newProxyInPackage.{package name}")}
 950      *               permission denies access.</li>
 951      *          </ul>
 952      * @throws  NullPointerException if the {@code interfaces} array
 953      *          argument or any of its elements are {@code null}, or
 954      *          if the invocation handler, {@code h}, is
 955      *          {@code null}
 956      *
 957      * @see <a href="#membership">Package and Module Membership of Proxy Class</a>


 958      */
 959     @CallerSensitive
 960     public static Object newProxyInstance(ClassLoader loader,
 961                                           Class<?>[] interfaces,
 962                                           InvocationHandler h) {
 963         Objects.requireNonNull(h);
 964 
 965         final Class<?> caller = System.getSecurityManager() == null
 966                                     ? null
 967                                     : Reflection.getCallerClass();
 968 
 969         /*
 970          * Look up or generate the designated proxy class and its constructor.
 971          */
 972         Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
 973 
 974         return newProxyInstance(caller, cons, h);
 975     }
 976 
 977     private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager


1022 
1023     /**
1024      * Returns the class loader for the given module.
1025      */
1026     private static ClassLoader getLoader(Module m) {
1027         PrivilegedAction<ClassLoader> pa = m::getClassLoader;
1028         return AccessController.doPrivileged(pa);
1029     }
1030 
1031     /**
1032      * Returns true if the given class is a proxy class.
1033      *
1034      * @implNote The reliability of this method is important for the ability
1035      * to use it to make security decisions, so its implementation should
1036      * not just test if the class in question extends {@code Proxy}.
1037      *
1038      * @param   cl the class to test
1039      * @return  {@code true} if the class is a proxy class and
1040      *          {@code false} otherwise
1041      * @throws  NullPointerException if {@code cl} is {@code null}



1042      */
1043     public static boolean isProxyClass(Class<?> cl) {
1044         return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
1045     }
1046 
1047     /**
1048      * Returns the invocation handler for the specified proxy instance.
1049      *
1050      * @param   proxy the proxy instance to return the invocation handler for
1051      * @return  the invocation handler for the proxy instance
1052      * @throws  IllegalArgumentException if the argument is not a
1053      *          proxy instance
1054      * @throws  SecurityException if a security manager, <em>s</em>, is present
1055      *          and the caller's class loader is not the same as or an
1056      *          ancestor of the class loader for the invocation handler
1057      *          and invocation of {@link SecurityManager#checkPackageAccess
1058      *          s.checkPackageAccess()} denies access to the invocation
1059      *          handler's class.
1060      */
1061     @CallerSensitive




 147  * the same manner as interface method invocations are encoded and
 148  * dispatched, as described above.  The declaring class of the
 149  * {@code Method} object passed to {@code invoke} will be
 150  * {@code java.lang.Object}.  Other public methods of a proxy
 151  * instance inherited from {@code java.lang.Object} are not
 152  * overridden by a proxy class, so invocations of those methods behave
 153  * like they do for instances of {@code java.lang.Object}.
 154  * </ul>
 155  *
 156  * <h3><a name="membership">Package and Module Membership of Proxy Class</a></h3>
 157  *
 158  * The package and module to which a proxy class belongs are chosen such that
 159  * the accessibility of the proxy class is in line with the accessibility of
 160  * the proxy interfaces. Specifically, the package and the module membership
 161  * of a proxy class defined via the
 162  * {@link Proxy#getProxyClass(ClassLoader, Class[])} or
 163  * {@link Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)}
 164  * methods is specified as follows:
 165  *
 166  * <ol>
 167  * <li>If all the proxy interfaces are in <em>exported</em> or <em>open</em>
 168  *     packages:
 169  * <ol type="a">
 170  * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
 171  *     <em>public</em> in a package exported by the
 172  *     {@linkplain ClassLoader#getUnnamedModule() unnamed module} of the specified
 173  *     loader. The name of the package is unspecified.</li>
 174  *
 175  * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then
 176  *     the proxy class is <em>non-public</em> in the package and module of the
 177  *     non-public interfaces. All the non-public interfaces must be in the same
 178  *     package and module; otherwise, proxying them is
 179  *     <a href="#restrictions">not possible</a>.</li>
 180  * </ol>
 181  * </li>
 182  * <li>If at least one proxy interface is in a package that is
 183  *     <em>non-exported</em> and <em>non-open</em>:
 184  * <ol type="a">
 185  * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
 186  *     <em>public</em> in a <em>non-exported</em>, <em>non-open</em> package of
 187  *     <a href="#dynamicmodule"><em>dynamic module</em>.</a>
 188  *     The names of the package and the module are unspecified.</li>
 189  *
 190  * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then
 191  *     the proxy class is <em>non-public</em> in the package and module of the
 192  *     non-public interfaces. All the non-public interfaces must be in the same
 193  *     package and module; otherwise, proxying them is
 194  *     <a href="#restrictions">not possible</a>.</li>
 195  * </ol>
 196  * </li>
 197  * </ol>
 198  *
 199  * <p>
 200  * Note that if proxy interfaces with a mix of accessibilities -- for example,
 201  * an exported public interface and a non-exported non-public interface -- are
 202  * proxied by the same instance, then the proxy class's accessibility is
 203  * governed by the least accessible proxy interface.
 204  * <p>
 205  * Note that it is possible for arbitrary code to obtain access to a proxy class
 206  * in an open package with {@link AccessibleObject#setAccessible setAccessible},
 207  * whereas a proxy class in a non-open package is never accessible to
 208  * code outside the module of the proxy class.
 209  *
 210  * <p>
 211  * Throughout this specification, a "non-exported package" refers to a package
 212  * that is not exported to all modules, and a "non-open package" refers to
 213  * a package that is not open to all modules.  Specifically, these terms refer to
 214  * a package that either is not exported/open by its containing module or is
 215  * exported/open in a qualified fashion by its containing module.
 216  *
 217  * <h3><a name="dynamicmodule">Dynamic Modules</a></h3>
 218  * <p>
 219  * A dynamic module is a named module generated at runtime. A proxy class
 220  * defined in a dynamic module is encapsulated and not accessible to any module.
 221  * Calling {@link Constructor#newInstance(Object...)} on a proxy class in
 222  * a dynamic module will throw {@code IllegalAccessException};
 223  * {@code Proxy.newProxyInstance} method should be used instead.
 224  *
 225  * <p>
 226  * A dynamic module can read the modules of all of the superinterfaces of a proxy class
 227  * and the modules of the types referenced by all public method signatures
 228  * of a proxy class.  If a superinterface or a referenced type, say {@code T},
 229  * is in a non-exported package, the {@linkplain java.lang.reflect.Module module}
 230  * of {@code T} is updated to export the package of {@code T} to the dynamic module.
 231  *
 232  * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
 233  *
 234  * <p>When two or more proxy interfaces contain a method with
 235  * the same name and parameter signature, the order of the proxy class's


 258  * which {@code Method} object to pass to the invocation handler.
 259  *
 260  * <p>Note also that when a duplicate method is dispatched to an
 261  * invocation handler, the {@code invoke} method may only throw
 262  * checked exception types that are assignable to one of the exception
 263  * types in the {@code throws} clause of the method in <i>all</i> of
 264  * the proxy interfaces that it can be invoked through.  If the
 265  * {@code invoke} method throws a checked exception that is not
 266  * assignable to any of the exception types declared by the method in one
 267  * of the proxy interfaces that it can be invoked through, then an
 268  * unchecked {@code UndeclaredThrowableException} will be thrown by
 269  * the invocation on the proxy instance.  This restriction means that not
 270  * all of the exception types returned by invoking
 271  * {@code getExceptionTypes} on the {@code Method} object
 272  * passed to the {@code invoke} method can necessarily be thrown
 273  * successfully by the {@code invoke} method.
 274  *
 275  * @author      Peter Jones
 276  * @see         InvocationHandler
 277  * @since       1.3
 278  * @revised 9
 279  * @spec JPMS
 280  */
 281 public class Proxy implements java.io.Serializable {
 282     private static final long serialVersionUID = -2222568056686623797L;
 283 
 284     /** parameter types of a proxy class constructor */
 285     private static final Class<?>[] constructorParams =
 286         { InvocationHandler.class };
 287 
 288     /**
 289      * a cache of proxy constructors with
 290      * {@link Constructor#setAccessible(boolean) accessible} flag already set
 291      */
 292     private static final ClassLoaderValue<Constructor<?>> proxyCache =
 293         new ClassLoaderValue<>();
 294 
 295     /**
 296      * the invocation handler for this proxy instance.
 297      * @serial
 298      */
 299     protected InvocationHandler h;


 346      *             s.checkPermission} with
 347      *             {@code RuntimePermission("getClassLoader")} permission
 348      *             denies access.</li>
 349      *             <li> for each proxy interface, {@code intf},
 350      *             the caller's class loader is not the same as or an
 351      *             ancestor of the class loader for {@code intf} and
 352      *             invocation of {@link SecurityManager#checkPackageAccess
 353      *             s.checkPackageAccess()} denies access to {@code intf}.</li>
 354      *          </ul>
 355      * @throws  NullPointerException if the {@code interfaces} array
 356      *          argument or any of its elements are {@code null}
 357      *
 358      * @deprecated Proxy classes generated in a named module are encapsulated and not
 359      *      accessible to code outside its module.
 360      *      {@link Constructor#newInstance(Object...) Constructor.newInstance} will throw
 361      *      {@code IllegalAccessException} when it is called on an inaccessible proxy class.
 362      *      Use {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)}
 363      *      to create a proxy instance instead.
 364      *
 365      * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
 366      * @revised 9
 367      * @spec JPMS
 368      */
 369     @Deprecated
 370     @CallerSensitive
 371     public static Class<?> getProxyClass(ClassLoader loader,
 372                                          Class<?>... interfaces)
 373         throws IllegalArgumentException
 374     {
 375         Class<?> caller = System.getSecurityManager() == null
 376                               ? null
 377                               : Reflection.getCallerClass();
 378 
 379         return getProxyConstructor(caller, loader, interfaces)
 380             .getDeclaringClass();
 381     }
 382 
 383     /**
 384      * Returns the {@code Constructor} object of a proxy class that takes a
 385      * single argument of type {@link InvocationHandler}, given a class loader
 386      * and an array of interfaces. The returned constructor will have the
 387      * {@link Constructor#setAccessible(boolean) accessible} flag already set.


 945      *               {@code RuntimePermission("getClassLoader")} permission
 946      *               denies access;</li>
 947      *          <li> for each proxy interface, {@code intf},
 948      *               the caller's class loader is not the same as or an
 949      *               ancestor of the class loader for {@code intf} and
 950      *               invocation of {@link SecurityManager#checkPackageAccess
 951      *               s.checkPackageAccess()} denies access to {@code intf};</li>
 952      *          <li> any of the given proxy interfaces is non-public and the
 953      *               caller class is not in the same {@linkplain Package runtime package}
 954      *               as the non-public interface and the invocation of
 955      *               {@link SecurityManager#checkPermission s.checkPermission} with
 956      *               {@code ReflectPermission("newProxyInPackage.{package name}")}
 957      *               permission denies access.</li>
 958      *          </ul>
 959      * @throws  NullPointerException if the {@code interfaces} array
 960      *          argument or any of its elements are {@code null}, or
 961      *          if the invocation handler, {@code h}, is
 962      *          {@code null}
 963      *
 964      * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
 965      * @revised 9
 966      * @spec JPMS
 967      */
 968     @CallerSensitive
 969     public static Object newProxyInstance(ClassLoader loader,
 970                                           Class<?>[] interfaces,
 971                                           InvocationHandler h) {
 972         Objects.requireNonNull(h);
 973 
 974         final Class<?> caller = System.getSecurityManager() == null
 975                                     ? null
 976                                     : Reflection.getCallerClass();
 977 
 978         /*
 979          * Look up or generate the designated proxy class and its constructor.
 980          */
 981         Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
 982 
 983         return newProxyInstance(caller, cons, h);
 984     }
 985 
 986     private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager


1031 
1032     /**
1033      * Returns the class loader for the given module.
1034      */
1035     private static ClassLoader getLoader(Module m) {
1036         PrivilegedAction<ClassLoader> pa = m::getClassLoader;
1037         return AccessController.doPrivileged(pa);
1038     }
1039 
1040     /**
1041      * Returns true if the given class is a proxy class.
1042      *
1043      * @implNote The reliability of this method is important for the ability
1044      * to use it to make security decisions, so its implementation should
1045      * not just test if the class in question extends {@code Proxy}.
1046      *
1047      * @param   cl the class to test
1048      * @return  {@code true} if the class is a proxy class and
1049      *          {@code false} otherwise
1050      * @throws  NullPointerException if {@code cl} is {@code null}
1051      *
1052      * @revised 9
1053      * @spec JPMS
1054      */
1055     public static boolean isProxyClass(Class<?> cl) {
1056         return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
1057     }
1058 
1059     /**
1060      * Returns the invocation handler for the specified proxy instance.
1061      *
1062      * @param   proxy the proxy instance to return the invocation handler for
1063      * @return  the invocation handler for the proxy instance
1064      * @throws  IllegalArgumentException if the argument is not a
1065      *          proxy instance
1066      * @throws  SecurityException if a security manager, <em>s</em>, is present
1067      *          and the caller's class loader is not the same as or an
1068      *          ancestor of the class loader for the invocation handler
1069      *          and invocation of {@link SecurityManager#checkPackageAccess
1070      *          s.checkPackageAccess()} denies access to the invocation
1071      *          handler's class.
1072      */
1073     @CallerSensitive


< prev index next >