1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Proxy.java Tue Feb 26 16:54:16 2013 +0100
1.3 @@ -0,0 +1,407 @@
1.4 +/*
1.5 + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang.reflect;
1.30 +
1.31 +
1.32 +/**
1.33 + * {@code Proxy} provides static methods for creating dynamic proxy
1.34 + * classes and instances, and it is also the superclass of all
1.35 + * dynamic proxy classes created by those methods.
1.36 + *
1.37 + * <p>To create a proxy for some interface {@code Foo}:
1.38 + * <pre>
1.39 + * InvocationHandler handler = new MyInvocationHandler(...);
1.40 + * Class proxyClass = Proxy.getProxyClass(
1.41 + * Foo.class.getClassLoader(), new Class[] { Foo.class });
1.42 + * Foo f = (Foo) proxyClass.
1.43 + * getConstructor(new Class[] { InvocationHandler.class }).
1.44 + * newInstance(new Object[] { handler });
1.45 + * </pre>
1.46 + * or more simply:
1.47 + * <pre>
1.48 + * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
1.49 + * new Class[] { Foo.class },
1.50 + * handler);
1.51 + * </pre>
1.52 + *
1.53 + * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
1.54 + * class</i> below) is a class that implements a list of interfaces
1.55 + * specified at runtime when the class is created, with behavior as
1.56 + * described below.
1.57 + *
1.58 + * A <i>proxy interface</i> is such an interface that is implemented
1.59 + * by a proxy class.
1.60 + *
1.61 + * A <i>proxy instance</i> is an instance of a proxy class.
1.62 + *
1.63 + * Each proxy instance has an associated <i>invocation handler</i>
1.64 + * object, which implements the interface {@link InvocationHandler}.
1.65 + * A method invocation on a proxy instance through one of its proxy
1.66 + * interfaces will be dispatched to the {@link InvocationHandler#invoke
1.67 + * invoke} method of the instance's invocation handler, passing the proxy
1.68 + * instance, a {@code java.lang.reflect.Method} object identifying
1.69 + * the method that was invoked, and an array of type {@code Object}
1.70 + * containing the arguments. The invocation handler processes the
1.71 + * encoded method invocation as appropriate and the result that it
1.72 + * returns will be returned as the result of the method invocation on
1.73 + * the proxy instance.
1.74 + *
1.75 + * <p>A proxy class has the following properties:
1.76 + *
1.77 + * <ul>
1.78 + * <li>Proxy classes are public, final, and not abstract.
1.79 + *
1.80 + * <li>The unqualified name of a proxy class is unspecified. The space
1.81 + * of class names that begin with the string {@code "$Proxy"}
1.82 + * should be, however, reserved for proxy classes.
1.83 + *
1.84 + * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
1.85 + *
1.86 + * <li>A proxy class implements exactly the interfaces specified at its
1.87 + * creation, in the same order.
1.88 + *
1.89 + * <li>If a proxy class implements a non-public interface, then it will
1.90 + * be defined in the same package as that interface. Otherwise, the
1.91 + * package of a proxy class is also unspecified. Note that package
1.92 + * sealing will not prevent a proxy class from being successfully defined
1.93 + * in a particular package at runtime, and neither will classes already
1.94 + * defined by the same class loader and the same package with particular
1.95 + * signers.
1.96 + *
1.97 + * <li>Since a proxy class implements all of the interfaces specified at
1.98 + * its creation, invoking {@code getInterfaces} on its
1.99 + * {@code Class} object will return an array containing the same
1.100 + * list of interfaces (in the order specified at its creation), invoking
1.101 + * {@code getMethods} on its {@code Class} object will return
1.102 + * an array of {@code Method} objects that include all of the
1.103 + * methods in those interfaces, and invoking {@code getMethod} will
1.104 + * find methods in the proxy interfaces as would be expected.
1.105 + *
1.106 + * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
1.107 + * return true if it is passed a proxy class-- a class returned by
1.108 + * {@code Proxy.getProxyClass} or the class of an object returned by
1.109 + * {@code Proxy.newProxyInstance}-- and false otherwise.
1.110 + *
1.111 + * <li>The {@code java.security.ProtectionDomain} of a proxy class
1.112 + * is the same as that of system classes loaded by the bootstrap class
1.113 + * loader, such as {@code java.lang.Object}, because the code for a
1.114 + * proxy class is generated by trusted system code. This protection
1.115 + * domain will typically be granted
1.116 + * {@code java.security.AllPermission}.
1.117 + *
1.118 + * <li>Each proxy class has one public constructor that takes one argument,
1.119 + * an implementation of the interface {@link InvocationHandler}, to set
1.120 + * the invocation handler for a proxy instance. Rather than having to use
1.121 + * the reflection API to access the public constructor, a proxy instance
1.122 + * can be also be created by calling the {@link Proxy#newProxyInstance
1.123 + * Proxy.newProxyInstance} method, which combines the actions of calling
1.124 + * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
1.125 + * constructor with an invocation handler.
1.126 + * </ul>
1.127 + *
1.128 + * <p>A proxy instance has the following properties:
1.129 + *
1.130 + * <ul>
1.131 + * <li>Given a proxy instance {@code proxy} and one of the
1.132 + * interfaces implemented by its proxy class {@code Foo}, the
1.133 + * following expression will return true:
1.134 + * <pre>
1.135 + * {@code proxy instanceof Foo}
1.136 + * </pre>
1.137 + * and the following cast operation will succeed (rather than throwing
1.138 + * a {@code ClassCastException}):
1.139 + * <pre>
1.140 + * {@code (Foo) proxy}
1.141 + * </pre>
1.142 + *
1.143 + * <li>Each proxy instance has an associated invocation handler, the one
1.144 + * that was passed to its constructor. The static
1.145 + * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
1.146 + * will return the invocation handler associated with the proxy instance
1.147 + * passed as its argument.
1.148 + *
1.149 + * <li>An interface method invocation on a proxy instance will be
1.150 + * encoded and dispatched to the invocation handler's {@link
1.151 + * InvocationHandler#invoke invoke} method as described in the
1.152 + * documentation for that method.
1.153 + *
1.154 + * <li>An invocation of the {@code hashCode},
1.155 + * {@code equals}, or {@code toString} methods declared in
1.156 + * {@code java.lang.Object} on a proxy instance will be encoded and
1.157 + * dispatched to the invocation handler's {@code invoke} method in
1.158 + * the same manner as interface method invocations are encoded and
1.159 + * dispatched, as described above. The declaring class of the
1.160 + * {@code Method} object passed to {@code invoke} will be
1.161 + * {@code java.lang.Object}. Other public methods of a proxy
1.162 + * instance inherited from {@code java.lang.Object} are not
1.163 + * overridden by a proxy class, so invocations of those methods behave
1.164 + * like they do for instances of {@code java.lang.Object}.
1.165 + * </ul>
1.166 + *
1.167 + * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
1.168 + *
1.169 + * <p>When two or more interfaces of a proxy class contain a method with
1.170 + * the same name and parameter signature, the order of the proxy class's
1.171 + * interfaces becomes significant. When such a <i>duplicate method</i>
1.172 + * is invoked on a proxy instance, the {@code Method} object passed
1.173 + * to the invocation handler will not necessarily be the one whose
1.174 + * declaring class is assignable from the reference type of the interface
1.175 + * that the proxy's method was invoked through. This limitation exists
1.176 + * because the corresponding method implementation in the generated proxy
1.177 + * class cannot determine which interface it was invoked through.
1.178 + * Therefore, when a duplicate method is invoked on a proxy instance,
1.179 + * the {@code Method} object for the method in the foremost interface
1.180 + * that contains the method (either directly or inherited through a
1.181 + * superinterface) in the proxy class's list of interfaces is passed to
1.182 + * the invocation handler's {@code invoke} method, regardless of the
1.183 + * reference type through which the method invocation occurred.
1.184 + *
1.185 + * <p>If a proxy interface contains a method with the same name and
1.186 + * parameter signature as the {@code hashCode}, {@code equals},
1.187 + * or {@code toString} methods of {@code java.lang.Object},
1.188 + * when such a method is invoked on a proxy instance, the
1.189 + * {@code Method} object passed to the invocation handler will have
1.190 + * {@code java.lang.Object} as its declaring class. In other words,
1.191 + * the public, non-final methods of {@code java.lang.Object}
1.192 + * logically precede all of the proxy interfaces for the determination of
1.193 + * which {@code Method} object to pass to the invocation handler.
1.194 + *
1.195 + * <p>Note also that when a duplicate method is dispatched to an
1.196 + * invocation handler, the {@code invoke} method may only throw
1.197 + * checked exception types that are assignable to one of the exception
1.198 + * types in the {@code throws} clause of the method in <i>all</i> of
1.199 + * the proxy interfaces that it can be invoked through. If the
1.200 + * {@code invoke} method throws a checked exception that is not
1.201 + * assignable to any of the exception types declared by the method in one
1.202 + * of the proxy interfaces that it can be invoked through, then an
1.203 + * unchecked {@code UndeclaredThrowableException} will be thrown by
1.204 + * the invocation on the proxy instance. This restriction means that not
1.205 + * all of the exception types returned by invoking
1.206 + * {@code getExceptionTypes} on the {@code Method} object
1.207 + * passed to the {@code invoke} method can necessarily be thrown
1.208 + * successfully by the {@code invoke} method.
1.209 + *
1.210 + * @author Peter Jones
1.211 + * @see InvocationHandler
1.212 + * @since 1.3
1.213 + */
1.214 +public class Proxy implements java.io.Serializable {
1.215 +
1.216 + private static final long serialVersionUID = -2222568056686623797L;
1.217 +
1.218 +
1.219 +
1.220 + /**
1.221 + * the invocation handler for this proxy instance.
1.222 + * @serial
1.223 + */
1.224 + protected InvocationHandler h;
1.225 +
1.226 + /**
1.227 + * Prohibits instantiation.
1.228 + */
1.229 + private Proxy() {
1.230 + }
1.231 +
1.232 + /**
1.233 + * Constructs a new {@code Proxy} instance from a subclass
1.234 + * (typically, a dynamic proxy class) with the specified value
1.235 + * for its invocation handler.
1.236 + *
1.237 + * @param h the invocation handler for this proxy instance
1.238 + */
1.239 + protected Proxy(InvocationHandler h) {
1.240 + this.h = h;
1.241 + }
1.242 +
1.243 + /**
1.244 + * Returns the {@code java.lang.Class} object for a proxy class
1.245 + * given a class loader and an array of interfaces. The proxy class
1.246 + * will be defined by the specified class loader and will implement
1.247 + * all of the supplied interfaces. If a proxy class for the same
1.248 + * permutation of interfaces has already been defined by the class
1.249 + * loader, then the existing proxy class will be returned; otherwise,
1.250 + * a proxy class for those interfaces will be generated dynamically
1.251 + * and defined by the class loader.
1.252 + *
1.253 + * <p>There are several restrictions on the parameters that may be
1.254 + * passed to {@code Proxy.getProxyClass}:
1.255 + *
1.256 + * <ul>
1.257 + * <li>All of the {@code Class} objects in the
1.258 + * {@code interfaces} array must represent interfaces, not
1.259 + * classes or primitive types.
1.260 + *
1.261 + * <li>No two elements in the {@code interfaces} array may
1.262 + * refer to identical {@code Class} objects.
1.263 + *
1.264 + * <li>All of the interface types must be visible by name through the
1.265 + * specified class loader. In other words, for class loader
1.266 + * {@code cl} and every interface {@code i}, the following
1.267 + * expression must be true:
1.268 + * <pre>
1.269 + * Class.forName(i.getName(), false, cl) == i
1.270 + * </pre>
1.271 + *
1.272 + * <li>All non-public interfaces must be in the same package;
1.273 + * otherwise, it would not be possible for the proxy class to
1.274 + * implement all of the interfaces, regardless of what package it is
1.275 + * defined in.
1.276 + *
1.277 + * <li>For any set of member methods of the specified interfaces
1.278 + * that have the same signature:
1.279 + * <ul>
1.280 + * <li>If the return type of any of the methods is a primitive
1.281 + * type or void, then all of the methods must have that same
1.282 + * return type.
1.283 + * <li>Otherwise, one of the methods must have a return type that
1.284 + * is assignable to all of the return types of the rest of the
1.285 + * methods.
1.286 + * </ul>
1.287 + *
1.288 + * <li>The resulting proxy class must not exceed any limits imposed
1.289 + * on classes by the virtual machine. For example, the VM may limit
1.290 + * the number of interfaces that a class may implement to 65535; in
1.291 + * that case, the size of the {@code interfaces} array must not
1.292 + * exceed 65535.
1.293 + * </ul>
1.294 + *
1.295 + * <p>If any of these restrictions are violated,
1.296 + * {@code Proxy.getProxyClass} will throw an
1.297 + * {@code IllegalArgumentException}. If the {@code interfaces}
1.298 + * array argument or any of its elements are {@code null}, a
1.299 + * {@code NullPointerException} will be thrown.
1.300 + *
1.301 + * <p>Note that the order of the specified proxy interfaces is
1.302 + * significant: two requests for a proxy class with the same combination
1.303 + * of interfaces but in a different order will result in two distinct
1.304 + * proxy classes.
1.305 + *
1.306 + * @param loader the class loader to define the proxy class
1.307 + * @param interfaces the list of interfaces for the proxy class
1.308 + * to implement
1.309 + * @return a proxy class that is defined in the specified class loader
1.310 + * and that implements the specified interfaces
1.311 + * @throws IllegalArgumentException if any of the restrictions on the
1.312 + * parameters that may be passed to {@code getProxyClass}
1.313 + * are violated
1.314 + * @throws NullPointerException if the {@code interfaces} array
1.315 + * argument or any of its elements are {@code null}
1.316 + */
1.317 + public static Class<?> getProxyClass(ClassLoader loader,
1.318 + Class<?>... interfaces)
1.319 + throws IllegalArgumentException
1.320 + {
1.321 + throw new IllegalArgumentException();
1.322 + }
1.323 +
1.324 + /**
1.325 + * Returns an instance of a proxy class for the specified interfaces
1.326 + * that dispatches method invocations to the specified invocation
1.327 + * handler. This method is equivalent to:
1.328 + * <pre>
1.329 + * Proxy.getProxyClass(loader, interfaces).
1.330 + * getConstructor(new Class[] { InvocationHandler.class }).
1.331 + * newInstance(new Object[] { handler });
1.332 + * </pre>
1.333 + *
1.334 + * <p>{@code Proxy.newProxyInstance} throws
1.335 + * {@code IllegalArgumentException} for the same reasons that
1.336 + * {@code Proxy.getProxyClass} does.
1.337 + *
1.338 + * @param loader the class loader to define the proxy class
1.339 + * @param interfaces the list of interfaces for the proxy class
1.340 + * to implement
1.341 + * @param h the invocation handler to dispatch method invocations to
1.342 + * @return a proxy instance with the specified invocation handler of a
1.343 + * proxy class that is defined by the specified class loader
1.344 + * and that implements the specified interfaces
1.345 + * @throws IllegalArgumentException if any of the restrictions on the
1.346 + * parameters that may be passed to {@code getProxyClass}
1.347 + * are violated
1.348 + * @throws NullPointerException if the {@code interfaces} array
1.349 + * argument or any of its elements are {@code null}, or
1.350 + * if the invocation handler, {@code h}, is
1.351 + * {@code null}
1.352 + */
1.353 + public static Object newProxyInstance(ClassLoader loader,
1.354 + Class<?>[] interfaces,
1.355 + InvocationHandler h)
1.356 + throws IllegalArgumentException
1.357 + {
1.358 + if (h == null) {
1.359 + throw new NullPointerException();
1.360 + }
1.361 + throw new IllegalArgumentException();
1.362 + }
1.363 +
1.364 + /**
1.365 + * Returns true if and only if the specified class was dynamically
1.366 + * generated to be a proxy class using the {@code getProxyClass}
1.367 + * method or the {@code newProxyInstance} method.
1.368 + *
1.369 + * <p>The reliability of this method is important for the ability
1.370 + * to use it to make security decisions, so its implementation should
1.371 + * not just test if the class in question extends {@code Proxy}.
1.372 + *
1.373 + * @param cl the class to test
1.374 + * @return {@code true} if the class is a proxy class and
1.375 + * {@code false} otherwise
1.376 + * @throws NullPointerException if {@code cl} is {@code null}
1.377 + */
1.378 + public static boolean isProxyClass(Class<?> cl) {
1.379 + if (cl == null) {
1.380 + throw new NullPointerException();
1.381 + }
1.382 +
1.383 + return false;
1.384 + }
1.385 +
1.386 + /**
1.387 + * Returns the invocation handler for the specified proxy instance.
1.388 + *
1.389 + * @param proxy the proxy instance to return the invocation handler for
1.390 + * @return the invocation handler for the proxy instance
1.391 + * @throws IllegalArgumentException if the argument is not a
1.392 + * proxy instance
1.393 + */
1.394 + public static InvocationHandler getInvocationHandler(Object proxy)
1.395 + throws IllegalArgumentException
1.396 + {
1.397 + /*
1.398 + * Verify that the object is actually a proxy instance.
1.399 + */
1.400 + if (!isProxyClass(proxy.getClass())) {
1.401 + throw new IllegalArgumentException("not a proxy instance");
1.402 + }
1.403 +
1.404 + Proxy p = (Proxy) proxy;
1.405 + return p.h;
1.406 + }
1.407 +
1.408 + private static native Class defineClass0(ClassLoader loader, String name,
1.409 + byte[] b, int off, int len);
1.410 +}