rt/emul/mini/src/main/java/java/lang/reflect/Proxy.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 604 emul/mini/src/main/java/java/lang/reflect/Proxy.java@3fcc279c921b
child 1378 9ee9b36adb53
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
jaroslav@601
     1
/*
jaroslav@601
     2
 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
jaroslav@601
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jaroslav@601
     4
 *
jaroslav@601
     5
 * This code is free software; you can redistribute it and/or modify it
jaroslav@601
     6
 * under the terms of the GNU General Public License version 2 only, as
jaroslav@601
     7
 * published by the Free Software Foundation.  Oracle designates this
jaroslav@601
     8
 * particular file as subject to the "Classpath" exception as provided
jaroslav@601
     9
 * by Oracle in the LICENSE file that accompanied this code.
jaroslav@601
    10
 *
jaroslav@601
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jaroslav@601
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jaroslav@601
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jaroslav@601
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jaroslav@601
    15
 * accompanied this code).
jaroslav@601
    16
 *
jaroslav@601
    17
 * You should have received a copy of the GNU General Public License version
jaroslav@601
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jaroslav@601
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jaroslav@601
    20
 *
jaroslav@601
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jaroslav@601
    22
 * or visit www.oracle.com if you need additional information or have any
jaroslav@601
    23
 * questions.
jaroslav@601
    24
 */
jaroslav@601
    25
jaroslav@601
    26
package java.lang.reflect;
jaroslav@601
    27
jaroslav@601
    28
jaroslav@601
    29
/**
jaroslav@601
    30
 * {@code Proxy} provides static methods for creating dynamic proxy
jaroslav@601
    31
 * classes and instances, and it is also the superclass of all
jaroslav@601
    32
 * dynamic proxy classes created by those methods.
jaroslav@601
    33
 *
jaroslav@601
    34
 * <p>To create a proxy for some interface {@code Foo}:
jaroslav@601
    35
 * <pre>
jaroslav@601
    36
 *     InvocationHandler handler = new MyInvocationHandler(...);
jaroslav@601
    37
 *     Class proxyClass = Proxy.getProxyClass(
jaroslav@601
    38
 *         Foo.class.getClassLoader(), new Class[] { Foo.class });
jaroslav@601
    39
 *     Foo f = (Foo) proxyClass.
jaroslav@601
    40
 *         getConstructor(new Class[] { InvocationHandler.class }).
jaroslav@601
    41
 *         newInstance(new Object[] { handler });
jaroslav@601
    42
 * </pre>
jaroslav@601
    43
 * or more simply:
jaroslav@601
    44
 * <pre>
jaroslav@601
    45
 *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
jaroslav@601
    46
 *                                          new Class[] { Foo.class },
jaroslav@601
    47
 *                                          handler);
jaroslav@601
    48
 * </pre>
jaroslav@601
    49
 *
jaroslav@601
    50
 * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
jaroslav@601
    51
 * class</i> below) is a class that implements a list of interfaces
jaroslav@601
    52
 * specified at runtime when the class is created, with behavior as
jaroslav@601
    53
 * described below.
jaroslav@601
    54
 *
jaroslav@601
    55
 * A <i>proxy interface</i> is such an interface that is implemented
jaroslav@601
    56
 * by a proxy class.
jaroslav@601
    57
 *
jaroslav@601
    58
 * A <i>proxy instance</i> is an instance of a proxy class.
jaroslav@601
    59
 *
jaroslav@601
    60
 * Each proxy instance has an associated <i>invocation handler</i>
jaroslav@601
    61
 * object, which implements the interface {@link InvocationHandler}.
jaroslav@601
    62
 * A method invocation on a proxy instance through one of its proxy
jaroslav@601
    63
 * interfaces will be dispatched to the {@link InvocationHandler#invoke
jaroslav@601
    64
 * invoke} method of the instance's invocation handler, passing the proxy
jaroslav@601
    65
 * instance, a {@code java.lang.reflect.Method} object identifying
jaroslav@601
    66
 * the method that was invoked, and an array of type {@code Object}
jaroslav@601
    67
 * containing the arguments.  The invocation handler processes the
jaroslav@601
    68
 * encoded method invocation as appropriate and the result that it
jaroslav@601
    69
 * returns will be returned as the result of the method invocation on
jaroslav@601
    70
 * the proxy instance.
jaroslav@601
    71
 *
jaroslav@601
    72
 * <p>A proxy class has the following properties:
jaroslav@601
    73
 *
jaroslav@601
    74
 * <ul>
jaroslav@601
    75
 * <li>Proxy classes are public, final, and not abstract.
jaroslav@601
    76
 *
jaroslav@601
    77
 * <li>The unqualified name of a proxy class is unspecified.  The space
jaroslav@601
    78
 * of class names that begin with the string {@code "$Proxy"}
jaroslav@601
    79
 * should be, however, reserved for proxy classes.
jaroslav@601
    80
 *
jaroslav@601
    81
 * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
jaroslav@601
    82
 *
jaroslav@601
    83
 * <li>A proxy class implements exactly the interfaces specified at its
jaroslav@601
    84
 * creation, in the same order.
jaroslav@601
    85
 *
jaroslav@601
    86
 * <li>If a proxy class implements a non-public interface, then it will
jaroslav@601
    87
 * be defined in the same package as that interface.  Otherwise, the
jaroslav@601
    88
 * package of a proxy class is also unspecified.  Note that package
jaroslav@601
    89
 * sealing will not prevent a proxy class from being successfully defined
jaroslav@601
    90
 * in a particular package at runtime, and neither will classes already
jaroslav@601
    91
 * defined by the same class loader and the same package with particular
jaroslav@601
    92
 * signers.
jaroslav@601
    93
 *
jaroslav@601
    94
 * <li>Since a proxy class implements all of the interfaces specified at
jaroslav@601
    95
 * its creation, invoking {@code getInterfaces} on its
jaroslav@601
    96
 * {@code Class} object will return an array containing the same
jaroslav@601
    97
 * list of interfaces (in the order specified at its creation), invoking
jaroslav@601
    98
 * {@code getMethods} on its {@code Class} object will return
jaroslav@601
    99
 * an array of {@code Method} objects that include all of the
jaroslav@601
   100
 * methods in those interfaces, and invoking {@code getMethod} will
jaroslav@601
   101
 * find methods in the proxy interfaces as would be expected.
jaroslav@601
   102
 *
jaroslav@601
   103
 * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
jaroslav@601
   104
 * return true if it is passed a proxy class-- a class returned by
jaroslav@601
   105
 * {@code Proxy.getProxyClass} or the class of an object returned by
jaroslav@601
   106
 * {@code Proxy.newProxyInstance}-- and false otherwise.
jaroslav@601
   107
 *
jaroslav@601
   108
 * <li>The {@code java.security.ProtectionDomain} of a proxy class
jaroslav@601
   109
 * is the same as that of system classes loaded by the bootstrap class
jaroslav@601
   110
 * loader, such as {@code java.lang.Object}, because the code for a
jaroslav@601
   111
 * proxy class is generated by trusted system code.  This protection
jaroslav@601
   112
 * domain will typically be granted
jaroslav@601
   113
 * {@code java.security.AllPermission}.
jaroslav@601
   114
 *
jaroslav@601
   115
 * <li>Each proxy class has one public constructor that takes one argument,
jaroslav@601
   116
 * an implementation of the interface {@link InvocationHandler}, to set
jaroslav@601
   117
 * the invocation handler for a proxy instance.  Rather than having to use
jaroslav@601
   118
 * the reflection API to access the public constructor, a proxy instance
jaroslav@601
   119
 * can be also be created by calling the {@link Proxy#newProxyInstance
jaroslav@601
   120
 * Proxy.newProxyInstance} method, which combines the actions of calling
jaroslav@601
   121
 * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
jaroslav@601
   122
 * constructor with an invocation handler.
jaroslav@601
   123
 * </ul>
jaroslav@601
   124
 *
jaroslav@601
   125
 * <p>A proxy instance has the following properties:
jaroslav@601
   126
 *
jaroslav@601
   127
 * <ul>
jaroslav@601
   128
 * <li>Given a proxy instance {@code proxy} and one of the
jaroslav@601
   129
 * interfaces implemented by its proxy class {@code Foo}, the
jaroslav@601
   130
 * following expression will return true:
jaroslav@601
   131
 * <pre>
jaroslav@601
   132
 *     {@code proxy instanceof Foo}
jaroslav@601
   133
 * </pre>
jaroslav@601
   134
 * and the following cast operation will succeed (rather than throwing
jaroslav@601
   135
 * a {@code ClassCastException}):
jaroslav@601
   136
 * <pre>
jaroslav@601
   137
 *     {@code (Foo) proxy}
jaroslav@601
   138
 * </pre>
jaroslav@601
   139
 *
jaroslav@601
   140
 * <li>Each proxy instance has an associated invocation handler, the one
jaroslav@601
   141
 * that was passed to its constructor.  The static
jaroslav@601
   142
 * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
jaroslav@601
   143
 * will return the invocation handler associated with the proxy instance
jaroslav@601
   144
 * passed as its argument.
jaroslav@601
   145
 *
jaroslav@601
   146
 * <li>An interface method invocation on a proxy instance will be
jaroslav@601
   147
 * encoded and dispatched to the invocation handler's {@link
jaroslav@601
   148
 * InvocationHandler#invoke invoke} method as described in the
jaroslav@601
   149
 * documentation for that method.
jaroslav@601
   150
 *
jaroslav@601
   151
 * <li>An invocation of the {@code hashCode},
jaroslav@601
   152
 * {@code equals}, or {@code toString} methods declared in
jaroslav@601
   153
 * {@code java.lang.Object} on a proxy instance will be encoded and
jaroslav@601
   154
 * dispatched to the invocation handler's {@code invoke} method in
jaroslav@601
   155
 * the same manner as interface method invocations are encoded and
jaroslav@601
   156
 * dispatched, as described above.  The declaring class of the
jaroslav@601
   157
 * {@code Method} object passed to {@code invoke} will be
jaroslav@601
   158
 * {@code java.lang.Object}.  Other public methods of a proxy
jaroslav@601
   159
 * instance inherited from {@code java.lang.Object} are not
jaroslav@601
   160
 * overridden by a proxy class, so invocations of those methods behave
jaroslav@601
   161
 * like they do for instances of {@code java.lang.Object}.
jaroslav@601
   162
 * </ul>
jaroslav@601
   163
 *
jaroslav@601
   164
 * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
jaroslav@601
   165
 *
jaroslav@601
   166
 * <p>When two or more interfaces of a proxy class contain a method with
jaroslav@601
   167
 * the same name and parameter signature, the order of the proxy class's
jaroslav@601
   168
 * interfaces becomes significant.  When such a <i>duplicate method</i>
jaroslav@601
   169
 * is invoked on a proxy instance, the {@code Method} object passed
jaroslav@601
   170
 * to the invocation handler will not necessarily be the one whose
jaroslav@601
   171
 * declaring class is assignable from the reference type of the interface
jaroslav@601
   172
 * that the proxy's method was invoked through.  This limitation exists
jaroslav@601
   173
 * because the corresponding method implementation in the generated proxy
jaroslav@601
   174
 * class cannot determine which interface it was invoked through.
jaroslav@601
   175
 * Therefore, when a duplicate method is invoked on a proxy instance,
jaroslav@601
   176
 * the {@code Method} object for the method in the foremost interface
jaroslav@601
   177
 * that contains the method (either directly or inherited through a
jaroslav@601
   178
 * superinterface) in the proxy class's list of interfaces is passed to
jaroslav@601
   179
 * the invocation handler's {@code invoke} method, regardless of the
jaroslav@601
   180
 * reference type through which the method invocation occurred.
jaroslav@601
   181
 *
jaroslav@601
   182
 * <p>If a proxy interface contains a method with the same name and
jaroslav@601
   183
 * parameter signature as the {@code hashCode}, {@code equals},
jaroslav@601
   184
 * or {@code toString} methods of {@code java.lang.Object},
jaroslav@601
   185
 * when such a method is invoked on a proxy instance, the
jaroslav@601
   186
 * {@code Method} object passed to the invocation handler will have
jaroslav@601
   187
 * {@code java.lang.Object} as its declaring class.  In other words,
jaroslav@601
   188
 * the public, non-final methods of {@code java.lang.Object}
jaroslav@601
   189
 * logically precede all of the proxy interfaces for the determination of
jaroslav@601
   190
 * which {@code Method} object to pass to the invocation handler.
jaroslav@601
   191
 *
jaroslav@601
   192
 * <p>Note also that when a duplicate method is dispatched to an
jaroslav@601
   193
 * invocation handler, the {@code invoke} method may only throw
jaroslav@601
   194
 * checked exception types that are assignable to one of the exception
jaroslav@601
   195
 * types in the {@code throws} clause of the method in <i>all</i> of
jaroslav@601
   196
 * the proxy interfaces that it can be invoked through.  If the
jaroslav@601
   197
 * {@code invoke} method throws a checked exception that is not
jaroslav@601
   198
 * assignable to any of the exception types declared by the method in one
jaroslav@601
   199
 * of the proxy interfaces that it can be invoked through, then an
jaroslav@601
   200
 * unchecked {@code UndeclaredThrowableException} will be thrown by
jaroslav@601
   201
 * the invocation on the proxy instance.  This restriction means that not
jaroslav@601
   202
 * all of the exception types returned by invoking
jaroslav@601
   203
 * {@code getExceptionTypes} on the {@code Method} object
jaroslav@601
   204
 * passed to the {@code invoke} method can necessarily be thrown
jaroslav@601
   205
 * successfully by the {@code invoke} method.
jaroslav@601
   206
 *
jaroslav@601
   207
 * @author      Peter Jones
jaroslav@601
   208
 * @see         InvocationHandler
jaroslav@601
   209
 * @since       1.3
jaroslav@601
   210
 */
jaroslav@601
   211
public class Proxy implements java.io.Serializable {
jaroslav@601
   212
jaroslav@601
   213
    private static final long serialVersionUID = -2222568056686623797L;
jaroslav@601
   214
jaroslav@601
   215
jaroslav@601
   216
jaroslav@601
   217
    /**
jaroslav@601
   218
     * the invocation handler for this proxy instance.
jaroslav@601
   219
     * @serial
jaroslav@601
   220
     */
jaroslav@601
   221
    protected InvocationHandler h;
jaroslav@601
   222
jaroslav@601
   223
    /**
jaroslav@601
   224
     * Prohibits instantiation.
jaroslav@601
   225
     */
jaroslav@601
   226
    private Proxy() {
jaroslav@601
   227
    }
jaroslav@601
   228
jaroslav@601
   229
    /**
jaroslav@601
   230
     * Constructs a new {@code Proxy} instance from a subclass
jaroslav@601
   231
     * (typically, a dynamic proxy class) with the specified value
jaroslav@601
   232
     * for its invocation handler.
jaroslav@601
   233
     *
jaroslav@601
   234
     * @param   h the invocation handler for this proxy instance
jaroslav@601
   235
     */
jaroslav@601
   236
    protected Proxy(InvocationHandler h) {
jaroslav@601
   237
        this.h = h;
jaroslav@601
   238
    }
jaroslav@601
   239
jaroslav@601
   240
    /**
jaroslav@601
   241
     * Returns the {@code java.lang.Class} object for a proxy class
jaroslav@601
   242
     * given a class loader and an array of interfaces.  The proxy class
jaroslav@601
   243
     * will be defined by the specified class loader and will implement
jaroslav@601
   244
     * all of the supplied interfaces.  If a proxy class for the same
jaroslav@601
   245
     * permutation of interfaces has already been defined by the class
jaroslav@601
   246
     * loader, then the existing proxy class will be returned; otherwise,
jaroslav@601
   247
     * a proxy class for those interfaces will be generated dynamically
jaroslav@601
   248
     * and defined by the class loader.
jaroslav@601
   249
     *
jaroslav@601
   250
     * <p>There are several restrictions on the parameters that may be
jaroslav@601
   251
     * passed to {@code Proxy.getProxyClass}:
jaroslav@601
   252
     *
jaroslav@601
   253
     * <ul>
jaroslav@601
   254
     * <li>All of the {@code Class} objects in the
jaroslav@601
   255
     * {@code interfaces} array must represent interfaces, not
jaroslav@601
   256
     * classes or primitive types.
jaroslav@601
   257
     *
jaroslav@601
   258
     * <li>No two elements in the {@code interfaces} array may
jaroslav@601
   259
     * refer to identical {@code Class} objects.
jaroslav@601
   260
     *
jaroslav@601
   261
     * <li>All of the interface types must be visible by name through the
jaroslav@601
   262
     * specified class loader.  In other words, for class loader
jaroslav@601
   263
     * {@code cl} and every interface {@code i}, the following
jaroslav@601
   264
     * expression must be true:
jaroslav@601
   265
     * <pre>
jaroslav@601
   266
     *     Class.forName(i.getName(), false, cl) == i
jaroslav@601
   267
     * </pre>
jaroslav@601
   268
     *
jaroslav@601
   269
     * <li>All non-public interfaces must be in the same package;
jaroslav@601
   270
     * otherwise, it would not be possible for the proxy class to
jaroslav@601
   271
     * implement all of the interfaces, regardless of what package it is
jaroslav@601
   272
     * defined in.
jaroslav@601
   273
     *
jaroslav@601
   274
     * <li>For any set of member methods of the specified interfaces
jaroslav@601
   275
     * that have the same signature:
jaroslav@601
   276
     * <ul>
jaroslav@601
   277
     * <li>If the return type of any of the methods is a primitive
jaroslav@601
   278
     * type or void, then all of the methods must have that same
jaroslav@601
   279
     * return type.
jaroslav@601
   280
     * <li>Otherwise, one of the methods must have a return type that
jaroslav@601
   281
     * is assignable to all of the return types of the rest of the
jaroslav@601
   282
     * methods.
jaroslav@601
   283
     * </ul>
jaroslav@601
   284
     *
jaroslav@601
   285
     * <li>The resulting proxy class must not exceed any limits imposed
jaroslav@601
   286
     * on classes by the virtual machine.  For example, the VM may limit
jaroslav@601
   287
     * the number of interfaces that a class may implement to 65535; in
jaroslav@601
   288
     * that case, the size of the {@code interfaces} array must not
jaroslav@601
   289
     * exceed 65535.
jaroslav@601
   290
     * </ul>
jaroslav@601
   291
     *
jaroslav@601
   292
     * <p>If any of these restrictions are violated,
jaroslav@601
   293
     * {@code Proxy.getProxyClass} will throw an
jaroslav@601
   294
     * {@code IllegalArgumentException}.  If the {@code interfaces}
jaroslav@601
   295
     * array argument or any of its elements are {@code null}, a
jaroslav@601
   296
     * {@code NullPointerException} will be thrown.
jaroslav@601
   297
     *
jaroslav@601
   298
     * <p>Note that the order of the specified proxy interfaces is
jaroslav@601
   299
     * significant: two requests for a proxy class with the same combination
jaroslav@601
   300
     * of interfaces but in a different order will result in two distinct
jaroslav@601
   301
     * proxy classes.
jaroslav@601
   302
     *
jaroslav@601
   303
     * @param   loader the class loader to define the proxy class
jaroslav@601
   304
     * @param   interfaces the list of interfaces for the proxy class
jaroslav@601
   305
     *          to implement
jaroslav@601
   306
     * @return  a proxy class that is defined in the specified class loader
jaroslav@601
   307
     *          and that implements the specified interfaces
jaroslav@601
   308
     * @throws  IllegalArgumentException if any of the restrictions on the
jaroslav@601
   309
     *          parameters that may be passed to {@code getProxyClass}
jaroslav@601
   310
     *          are violated
jaroslav@601
   311
     * @throws  NullPointerException if the {@code interfaces} array
jaroslav@601
   312
     *          argument or any of its elements are {@code null}
jaroslav@601
   313
     */
jaroslav@601
   314
    public static Class<?> getProxyClass(ClassLoader loader,
jaroslav@601
   315
                                         Class<?>... interfaces)
jaroslav@601
   316
        throws IllegalArgumentException
jaroslav@601
   317
    {
jaroslav@604
   318
        throw new IllegalArgumentException();
jaroslav@601
   319
    }
jaroslav@601
   320
jaroslav@601
   321
    /**
jaroslav@601
   322
     * Returns an instance of a proxy class for the specified interfaces
jaroslav@601
   323
     * that dispatches method invocations to the specified invocation
jaroslav@601
   324
     * handler.  This method is equivalent to:
jaroslav@601
   325
     * <pre>
jaroslav@601
   326
     *     Proxy.getProxyClass(loader, interfaces).
jaroslav@601
   327
     *         getConstructor(new Class[] { InvocationHandler.class }).
jaroslav@601
   328
     *         newInstance(new Object[] { handler });
jaroslav@601
   329
     * </pre>
jaroslav@601
   330
     *
jaroslav@601
   331
     * <p>{@code Proxy.newProxyInstance} throws
jaroslav@601
   332
     * {@code IllegalArgumentException} for the same reasons that
jaroslav@601
   333
     * {@code Proxy.getProxyClass} does.
jaroslav@601
   334
     *
jaroslav@601
   335
     * @param   loader the class loader to define the proxy class
jaroslav@601
   336
     * @param   interfaces the list of interfaces for the proxy class
jaroslav@601
   337
     *          to implement
jaroslav@601
   338
     * @param   h the invocation handler to dispatch method invocations to
jaroslav@601
   339
     * @return  a proxy instance with the specified invocation handler of a
jaroslav@601
   340
     *          proxy class that is defined by the specified class loader
jaroslav@601
   341
     *          and that implements the specified interfaces
jaroslav@601
   342
     * @throws  IllegalArgumentException if any of the restrictions on the
jaroslav@601
   343
     *          parameters that may be passed to {@code getProxyClass}
jaroslav@601
   344
     *          are violated
jaroslav@601
   345
     * @throws  NullPointerException if the {@code interfaces} array
jaroslav@601
   346
     *          argument or any of its elements are {@code null}, or
jaroslav@601
   347
     *          if the invocation handler, {@code h}, is
jaroslav@601
   348
     *          {@code null}
jaroslav@601
   349
     */
jaroslav@601
   350
    public static Object newProxyInstance(ClassLoader loader,
jaroslav@601
   351
                                          Class<?>[] interfaces,
jaroslav@601
   352
                                          InvocationHandler h)
jaroslav@601
   353
        throws IllegalArgumentException
jaroslav@601
   354
    {
jaroslav@601
   355
        if (h == null) {
jaroslav@601
   356
            throw new NullPointerException();
jaroslav@601
   357
        }
jaroslav@604
   358
        throw new IllegalArgumentException();
jaroslav@601
   359
    }
jaroslav@601
   360
jaroslav@601
   361
    /**
jaroslav@601
   362
     * Returns true if and only if the specified class was dynamically
jaroslav@601
   363
     * generated to be a proxy class using the {@code getProxyClass}
jaroslav@601
   364
     * method or the {@code newProxyInstance} method.
jaroslav@601
   365
     *
jaroslav@601
   366
     * <p>The reliability of this method is important for the ability
jaroslav@601
   367
     * to use it to make security decisions, so its implementation should
jaroslav@601
   368
     * not just test if the class in question extends {@code Proxy}.
jaroslav@601
   369
     *
jaroslav@601
   370
     * @param   cl the class to test
jaroslav@601
   371
     * @return  {@code true} if the class is a proxy class and
jaroslav@601
   372
     *          {@code false} otherwise
jaroslav@601
   373
     * @throws  NullPointerException if {@code cl} is {@code null}
jaroslav@601
   374
     */
jaroslav@601
   375
    public static boolean isProxyClass(Class<?> cl) {
jaroslav@601
   376
        if (cl == null) {
jaroslav@601
   377
            throw new NullPointerException();
jaroslav@601
   378
        }
jaroslav@601
   379
jaroslav@604
   380
        return false;
jaroslav@601
   381
    }
jaroslav@601
   382
jaroslav@601
   383
    /**
jaroslav@601
   384
     * Returns the invocation handler for the specified proxy instance.
jaroslav@601
   385
     *
jaroslav@601
   386
     * @param   proxy the proxy instance to return the invocation handler for
jaroslav@601
   387
     * @return  the invocation handler for the proxy instance
jaroslav@601
   388
     * @throws  IllegalArgumentException if the argument is not a
jaroslav@601
   389
     *          proxy instance
jaroslav@601
   390
     */
jaroslav@601
   391
    public static InvocationHandler getInvocationHandler(Object proxy)
jaroslav@601
   392
        throws IllegalArgumentException
jaroslav@601
   393
    {
jaroslav@601
   394
        /*
jaroslav@601
   395
         * Verify that the object is actually a proxy instance.
jaroslav@601
   396
         */
jaroslav@601
   397
        if (!isProxyClass(proxy.getClass())) {
jaroslav@601
   398
            throw new IllegalArgumentException("not a proxy instance");
jaroslav@601
   399
        }
jaroslav@601
   400
jaroslav@601
   401
        Proxy p = (Proxy) proxy;
jaroslav@601
   402
        return p.h;
jaroslav@601
   403
    }
jaroslav@601
   404
jaroslav@601
   405
    private static native Class defineClass0(ClassLoader loader, String name,
jaroslav@601
   406
                                             byte[] b, int off, int len);
jaroslav@601
   407
}