jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java
author coffeys
Thu, 22 Sep 2016 17:21:10 +0100
changeset 41121 91734a3ed04b
parent 40459 88a91142b711
child 43712 5dfd0950317c
permissions -rw-r--r--
8151832: Improve exception messages in exception thrown by new JDK 9 code Reviewed-by: alanb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
21655
55f32ae4f920 8028229: Fix more raw types lint warning in core libraries
darcy
parents: 20825
diff changeset
     2
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3959
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.lang.reflect;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
    28
import java.security.AccessController;
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
    29
import java.security.PrivilegedAction;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.Arrays;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    31
import java.util.Collections;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    32
import java.util.HashMap;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    33
import java.util.HashSet;
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
    34
import java.util.IdentityHashMap;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    35
import java.util.List;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.Map;
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
    37
import java.util.Objects;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    38
import java.util.Set;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    39
import java.util.concurrent.atomic.AtomicInteger;
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
    40
import java.util.concurrent.atomic.AtomicLong;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    41
import java.util.stream.Collectors;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    42
import java.util.stream.Stream;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    43
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    44
import jdk.internal.loader.BootLoader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    45
import jdk.internal.module.Modules;
36669
17af8b44d311 8152642: Remove sun.misc.Unsafe dependency from java.lang.reflect.Proxy
chegar
parents: 36511
diff changeset
    46
import jdk.internal.misc.Unsafe;
34882
ce2a8ec851c1 8145544: Move sun.misc.VM to jdk.internal.misc
chegar
parents: 34704
diff changeset
    47
import jdk.internal.misc.VM;
37363
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 37349
diff changeset
    48
import jdk.internal.reflect.CallerSensitive;
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 37349
diff changeset
    49
import jdk.internal.reflect.Reflection;
40459
88a91142b711 8164547: Make java.lang.reflect.ClassLoaderValue public for internal use
plevart
parents: 37781
diff changeset
    50
import jdk.internal.loader.ClassLoaderValue;
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
    51
import sun.reflect.misc.ReflectUtil;
37593
824750ada3d6 8154231: Simplify access to System properties from JDK code
redestad
parents: 37363
diff changeset
    52
import sun.security.action.GetPropertyAction;
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
    53
import sun.security.util.SecurityConstants;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    57
 * {@code Proxy} provides static methods for creating objects that act like instances
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    58
 * of interfaces but allow for customized method invocation.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    59
 * To create a proxy instance for some interface {@code Foo}:
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    60
 * <pre>{@code
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *     InvocationHandler handler = new MyInvocationHandler(...);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    63
 *                                          new Class<?>[] { Foo.class },
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *                                          handler);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    65
 * }</pre>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    67
 * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    68
 * A <em>proxy class</em> is a class created at runtime that implements a specified
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    69
 * list of interfaces, known as <em>proxy interfaces</em>. A <em>proxy instance</em>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    70
 * is an instance of a proxy class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * Each proxy instance has an associated <i>invocation handler</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * object, which implements the interface {@link InvocationHandler}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * A method invocation on a proxy instance through one of its proxy
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * interfaces will be dispatched to the {@link InvocationHandler#invoke
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * invoke} method of the instance's invocation handler, passing the proxy
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * instance, a {@code java.lang.reflect.Method} object identifying
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * the method that was invoked, and an array of type {@code Object}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * containing the arguments.  The invocation handler processes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * encoded method invocation as appropriate and the result that it
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * returns will be returned as the result of the method invocation on
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * the proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * <p>A proxy class has the following properties:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * <li>The unqualified name of a proxy class is unspecified.  The space
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * of class names that begin with the string {@code "$Proxy"}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * should be, however, reserved for proxy classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    91
 * <li>The package and module in which a proxy class is defined is specified
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    92
 * <a href="#membership">below</a>.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    93
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    94
 * <li>A proxy class is <em>final and non-abstract</em>.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    95
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * <li>A proxy class implements exactly the interfaces specified at its
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    99
 * creation, in the same order. Invoking {@link Class#getInterfaces getInterfaces}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   100
 * on its {@code Class} object will return an array containing the same
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 * list of interfaces (in the order specified at its creation), invoking
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   102
 * {@link Class#getMethods getMethods} on its {@code Class} object will return
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 * an array of {@code Method} objects that include all of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 * methods in those interfaces, and invoking {@code getMethod} will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 * find methods in the proxy interfaces as would be expected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   107
 * <li>The {@link java.security.ProtectionDomain} of a proxy class
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * is the same as that of system classes loaded by the bootstrap class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * loader, such as {@code java.lang.Object}, because the code for a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 * proxy class is generated by trusted system code.  This protection
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   111
 * domain will typically be granted {@code java.security.AllPermission}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   113
 * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method can be used
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   114
 * to determine if a given class is a proxy class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
 * <p>A proxy instance has the following properties:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
 * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
 * <li>Given a proxy instance {@code proxy} and one of the
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   121
 * interfaces, {@code Foo}, implemented by its proxy class, the
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
 * following expression will return true:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 *     {@code proxy instanceof Foo}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
 * and the following cast operation will succeed (rather than throwing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
 * a {@code ClassCastException}):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
 *     {@code (Foo) proxy}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * <li>Each proxy instance has an associated invocation handler, the one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * that was passed to its constructor.  The static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
 * will return the invocation handler associated with the proxy instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
 * passed as its argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
 * <li>An interface method invocation on a proxy instance will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
 * encoded and dispatched to the invocation handler's {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
 * InvocationHandler#invoke invoke} method as described in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
 * documentation for that method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
 * <li>An invocation of the {@code hashCode},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
 * {@code equals}, or {@code toString} methods declared in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * {@code java.lang.Object} on a proxy instance will be encoded and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 * dispatched to the invocation handler's {@code invoke} method in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * the same manner as interface method invocations are encoded and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 * dispatched, as described above.  The declaring class of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
 * {@code Method} object passed to {@code invoke} will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
 * {@code java.lang.Object}.  Other public methods of a proxy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
 * instance inherited from {@code java.lang.Object} are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
 * overridden by a proxy class, so invocations of those methods behave
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
 * like they do for instances of {@code java.lang.Object}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
 * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   156
 * <h3><a name="membership">Package and Module Membership of Proxy Class</a></h3>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   157
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   158
 * The package and module to which a proxy class belongs are chosen such that
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   159
 * the accessibility of the proxy class is in line with the accessibility of
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   160
 * the proxy interfaces. Specifically, the package and the module membership
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   161
 * of a proxy class defined via the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   162
 * {@link Proxy#getProxyClass(ClassLoader, Class[])} or
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   163
 * {@link Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   164
 * methods is specified as follows:
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   165
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   166
 * <ol>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   167
 * <li>If all the proxy interfaces are in <em>exported</em> packages:
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   168
 * <ol type="a">
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   169
 * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   170
 *     <em>public</em> in a package exported by the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   171
 *     {@linkplain ClassLoader#getUnnamedModule() unnamed module} of the specified
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   172
 *     loader. The name of the package is unspecified.</li>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   173
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   174
 * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   175
 *     the proxy class is <em>non-public</em> in the package and module of the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   176
 *     non-public interfaces. All the non-public interfaces must be in the same
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   177
 *     package and module; otherwise, proxying them is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   178
 *     <a href="#restrictions">not possible</a>.</li>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   179
 * </ol>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   180
 * </li>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   181
 * <li>If at least one proxy interface is a <em>non-exported</em> package:
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   182
 * <ol type="a">
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   183
 * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   184
 *     <em>public</em> in a <em>non-exported</em> package of
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   185
 *     <a href="#dynamicmodule"><em>dynamic module</em>.</a>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   186
 *     The names of the package and the module are unspecified.</li>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   187
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   188
 * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   189
 *     the proxy class is <em>non-public</em> in the package and module of the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   190
 *     non-public interfaces. All the non-public interfaces must be in the same
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   191
 *     package and module; otherwise, proxying them is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   192
 *     <a href="#restrictions">not possible</a>.</li>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   193
 * </ol>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   194
 * </li>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   195
 * </ol>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   196
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   197
 * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   198
 * Note that if proxy interfaces with a mix of accessibilities --
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   199
 * exported public, exported non-public, non-exported public, non-exported non-public --
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   200
 * are proxied by the same instance, then the proxy class's accessibility is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   201
 * governed by the least accessible proxy interface.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   202
 * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   203
 * Note that it is possible for arbitrary code to obtain access to a proxy class
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   204
 * in an exported package with {@link AccessibleObject#setAccessible setAccessible},
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   205
 * whereas a proxy class in a non-exported package is never accessible to
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   206
 * code outside the module of the proxy class.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   207
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   208
 * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   209
 * Throughout this specification, a "non-exported package" refers to a package that
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   210
 * is not exported to all modules. Specifically, it refers to a package that
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   211
 * either is not exported at all by its containing module or is exported in a
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   212
 * qualified fashion by its containing module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   213
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   214
 * <h3><a name="dynamicmodule">Dynamic Modules</a></h3>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   215
 * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   216
 * A dynamic module is a named module generated at runtime. A proxy class
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   217
 * defined in a dynamic module is encapsulated and not accessible to any module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   218
 * Calling {@link Constructor#newInstance(Object...)} on a proxy class in
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   219
 * a dynamic module will throw {@code IllegalAccessException};
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   220
 * {@code Proxy.newProxyInstance} method should be used instead.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   221
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   222
 * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   223
 * A dynamic module can read the modules of all of the superinterfaces of a proxy class
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   224
 * and the modules of the types referenced by all public method signatures
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   225
 * of a proxy class.  If a superinterface or a referenced type, say {@code T},
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   226
 * is in a non-exported package, the {@linkplain java.lang.reflect.Module module}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   227
 * of {@code T} is updated to export the package of {@code T} to the dynamic module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   228
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
 * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
 *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   231
 * <p>When two or more proxy interfaces contain a method with
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
 * the same name and parameter signature, the order of the proxy class's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
 * interfaces becomes significant.  When such a <i>duplicate method</i>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
 * is invoked on a proxy instance, the {@code Method} object passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
 * to the invocation handler will not necessarily be the one whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
 * declaring class is assignable from the reference type of the interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
 * that the proxy's method was invoked through.  This limitation exists
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
 * because the corresponding method implementation in the generated proxy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
 * class cannot determine which interface it was invoked through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
 * Therefore, when a duplicate method is invoked on a proxy instance,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
 * the {@code Method} object for the method in the foremost interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
 * that contains the method (either directly or inherited through a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
 * superinterface) in the proxy class's list of interfaces is passed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
 * the invocation handler's {@code invoke} method, regardless of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
 * reference type through which the method invocation occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
 * <p>If a proxy interface contains a method with the same name and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
 * parameter signature as the {@code hashCode}, {@code equals},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
 * or {@code toString} methods of {@code java.lang.Object},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
 * when such a method is invoked on a proxy instance, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
 * {@code Method} object passed to the invocation handler will have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
 * {@code java.lang.Object} as its declaring class.  In other words,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
 * the public, non-final methods of {@code java.lang.Object}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
 * logically precede all of the proxy interfaces for the determination of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
 * which {@code Method} object to pass to the invocation handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
 * <p>Note also that when a duplicate method is dispatched to an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
 * invocation handler, the {@code invoke} method may only throw
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
 * checked exception types that are assignable to one of the exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
 * types in the {@code throws} clause of the method in <i>all</i> of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
 * the proxy interfaces that it can be invoked through.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
 * {@code invoke} method throws a checked exception that is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
 * assignable to any of the exception types declared by the method in one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
 * of the proxy interfaces that it can be invoked through, then an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
 * unchecked {@code UndeclaredThrowableException} will be thrown by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
 * the invocation on the proxy instance.  This restriction means that not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
 * all of the exception types returned by invoking
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
 * {@code getExceptionTypes} on the {@code Method} object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
 * passed to the {@code invoke} method can necessarily be thrown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
 * successfully by the {@code invoke} method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
 * @author      Peter Jones
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
 * @see         InvocationHandler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
 * @since       1.3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
public class Proxy implements java.io.Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    private static final long serialVersionUID = -2222568056686623797L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    /** parameter types of a proxy class constructor */
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   280
    private static final Class<?>[] constructorParams =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        { InvocationHandler.class };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   283
    /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   284
     * a cache of proxy constructors with
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   285
     * {@link Constructor#setAccessible(boolean) accessible} flag already set
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   286
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   287
    private static final ClassLoaderValue<Constructor<?>> proxyCache =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   288
        new ClassLoaderValue<>();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   289
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   290
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * the invocation handler for this proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    protected InvocationHandler h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * Prohibits instantiation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    private Proxy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * Constructs a new {@code Proxy} instance from a subclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * (typically, a dynamic proxy class) with the specified value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * for its invocation handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     *
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   307
     * @param  h the invocation handler for this proxy instance
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   308
     *
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   309
     * @throws NullPointerException if the given invocation handler, {@code h},
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   310
     *         is {@code null}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    protected Proxy(InvocationHandler h) {
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   313
        Objects.requireNonNull(h);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        this.h = h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * Returns the {@code java.lang.Class} object for a proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * given a class loader and an array of interfaces.  The proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * will be defined by the specified class loader and will implement
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   321
     * all of the supplied interfaces.  If any of the given interfaces
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   322
     * is non-public, the proxy class will be non-public. If a proxy class
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   323
     * for the same permutation of interfaces has already been defined by the
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   324
     * class loader, then the existing proxy class will be returned; otherwise,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * a proxy class for those interfaces will be generated dynamically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * and defined by the class loader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * @param   loader the class loader to define the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * @param   interfaces the list of interfaces for the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     *          to implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * @return  a proxy class that is defined in the specified class loader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     *          and that implements the specified interfaces
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   333
     * @throws  IllegalArgumentException if any of the <a href="#restrictions">
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   334
     *          restrictions</a> on the parameters are violated
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   335
     * @throws  SecurityException if a security manager, <em>s</em>, is present
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   336
     *          and any of the following conditions is met:
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   337
     *          <ul>
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   338
     *             <li> the given {@code loader} is {@code null} and
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   339
     *             the caller's class loader is not {@code null} and the
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   340
     *             invocation of {@link SecurityManager#checkPermission
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   341
     *             s.checkPermission} with
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   342
     *             {@code RuntimePermission("getClassLoader")} permission
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   343
     *             denies access.</li>
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   344
     *             <li> for each proxy interface, {@code intf},
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   345
     *             the caller's class loader is not the same as or an
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   346
     *             ancestor of the class loader for {@code intf} and
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   347
     *             invocation of {@link SecurityManager#checkPackageAccess
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   348
     *             s.checkPackageAccess()} denies access to {@code intf}.</li>
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   349
     *          </ul>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * @throws  NullPointerException if the {@code interfaces} array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     *          argument or any of its elements are {@code null}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   352
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   353
     * @deprecated Proxy classes generated in a named module are encapsulated and not
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   354
     *      accessible to code outside its module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   355
     *      {@link Constructor#newInstance(Object...) Constructor.newInstance} will throw
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   356
     *      {@code IllegalAccessException} when it is called on an inaccessible proxy class.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   357
     *      Use {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   358
     *      to create a proxy instance instead.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   359
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   360
     * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     */
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   362
    @Deprecated
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   363
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    public static Class<?> getProxyClass(ClassLoader loader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                                         Class<?>... interfaces)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        throws IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   368
        Class<?> caller = System.getSecurityManager() == null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   369
                              ? null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   370
                              : Reflection.getCallerClass();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   371
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   372
        return getProxyConstructor(caller, loader, interfaces)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   373
            .getDeclaringClass();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   374
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   375
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   376
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   377
     * Returns the {@code Constructor} object of a proxy class that takes a
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   378
     * single argument of type {@link InvocationHandler}, given a class loader
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   379
     * and an array of interfaces. The returned constructor will have the
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   380
     * {@link Constructor#setAccessible(boolean) accessible} flag already set.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   381
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   382
     * @param   caller passed from a public-facing @CallerSensitive method if
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   383
     *                 SecurityManager is set or {@code null} if there's no
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   384
     *                 SecurityManager
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   385
     * @param   loader the class loader to define the proxy class
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   386
     * @param   interfaces the list of interfaces for the proxy class
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   387
     *          to implement
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   388
     * @return  a Constructor of the proxy class taking single
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   389
     *          {@code InvocationHandler} parameter
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   390
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   391
    private static Constructor<?> getProxyConstructor(Class<?> caller,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   392
                                                      ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   393
                                                      Class<?>... interfaces)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   394
    {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   395
        // optimization for single interface
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   396
        if (interfaces.length == 1) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   397
            Class<?> intf = interfaces[0];
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   398
            if (caller != null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   399
                checkProxyAccess(caller, loader, intf);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   400
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   401
            return proxyCache.sub(intf).computeIfAbsent(
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   402
                loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   403
                (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   404
            );
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   405
        } else {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   406
            // interfaces cloned
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   407
            final Class<?>[] intfsArray = interfaces.clone();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   408
            if (caller != null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   409
                checkProxyAccess(caller, loader, intfsArray);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   410
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   411
            final List<Class<?>> intfs = Arrays.asList(intfsArray);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   412
            return proxyCache.sub(intfs).computeIfAbsent(
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   413
                loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   414
                (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   415
            );
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   416
        }
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   417
    }
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   418
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   419
    /*
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   420
     * Check permissions required to create a Proxy class.
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   421
     *
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   422
     * To define a proxy class, it performs the access checks as in
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   423
     * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   424
     * 1. "getClassLoader" permission check if loader == null
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   425
     * 2. checkPackageAccess on the interfaces it implements
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   426
     *
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   427
     * To get a constructor and new instance of a proxy class, it performs
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   428
     * the package access check on the interfaces it implements
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   429
     * as in Class.getConstructor.
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   430
     *
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   431
     * If an interface is non-public, the proxy class must be defined by
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   432
     * the defining loader of the interface.  If the caller's class loader
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   433
     * is not the same as the defining loader of the interface, the VM
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   434
     * will throw IllegalAccessError when the generated proxy class is
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   435
     * being defined.
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   436
     */
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   437
    private static void checkProxyAccess(Class<?> caller,
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   438
                                         ClassLoader loader,
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   439
                                         Class<?> ... interfaces)
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   440
    {
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   441
        SecurityManager sm = System.getSecurityManager();
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   442
        if (sm != null) {
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   443
            ClassLoader ccl = caller.getClassLoader();
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   444
            if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   445
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   446
            }
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   447
            ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   448
        }
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   449
    }
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   450
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   451
    /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   452
     * Builder for a proxy class.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   453
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   454
     * If the module is not specified in this ProxyBuilder constructor,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   455
     * it will map from the given loader and interfaces to the module
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   456
     * in which the proxy class will be defined.
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   457
     */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   458
    private static final class ProxyBuilder {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   459
        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   460
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   461
        // prefix for all proxy class names
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   462
        private static final String proxyClassNamePrefix = "$Proxy";
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   463
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   464
        // next number to use for generation of unique proxy class names
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   465
        private static final AtomicLong nextUniqueNumber = new AtomicLong();
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   466
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   467
        // a reverse cache of defined proxy classes
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   468
        private static final ClassLoaderValue<Boolean> reverseProxyCache =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   469
            new ClassLoaderValue<>();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   470
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   471
        private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            String proxyPkg = null;     // package to define proxy class in
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   473
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
             * Record the package of a non-public proxy interface so that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
             * proxy class will be defined in the same package.  Verify that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
             * all non-public proxy interfaces are in the same package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
             */
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   480
            for (Class<?> intf : interfaces) {
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   481
                int flags = intf.getModifiers();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                if (!Modifier.isPublic(flags)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   483
                    accessFlags = Modifier.FINAL;  // non-public, final
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   484
                    String pkg = intf.getPackageName();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                    if (proxyPkg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                        proxyPkg = pkg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                    } else if (!pkg.equals(proxyPkg)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                        throw new IllegalArgumentException(
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   489
                                "non-public interfaces from different packages");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   494
            if (proxyPkg == null) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   495
                // all proxy interfaces are public
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   496
                proxyPkg = m.isNamed() ? PROXY_PACKAGE_PREFIX + "." + m.getName()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   497
                                       : PROXY_PACKAGE_PREFIX;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   498
            } else if (proxyPkg.isEmpty() && m.isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   499
                throw new IllegalArgumentException(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   500
                        "Unnamed package cannot be added to " + m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   501
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   502
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   503
            // add the package to the runtime module if not exists
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   504
            if (m.isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   505
                m.addPackage(proxyPkg);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   508
            /*
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   509
             * Choose a name for the proxy class to generate.
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   510
             */
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   511
            long num = nextUniqueNumber.getAndIncrement();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   512
            String proxyName = proxyPkg.isEmpty() ? proxyClassNamePrefix + num
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   513
                                                  : proxyPkg + "." + proxyClassNamePrefix + num;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   514
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   515
            ClassLoader loader = getLoader(m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   516
            trace(proxyName, m, loader, interfaces);
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   517
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   518
            /*
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   519
             * Generate the specified proxy class.
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   520
             */
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   521
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   522
                    proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   523
            try {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   524
                Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   525
                                                 0, proxyClassFile.length,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   526
                                                 loader, null);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   527
                reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   528
                return pc;
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   529
            } catch (ClassFormatError e) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                /*
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   531
                 * A ClassFormatError here means that (barring bugs in the
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   532
                 * proxy class generation code) there was some other
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   533
                 * invalid aspect of the arguments supplied to the proxy
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   534
                 * class creation (such as virtual machine limitations
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   535
                 * exceeded).
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                 */
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   537
                throw new IllegalArgumentException(e.toString());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   540
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   541
        /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   542
         * Test if given class is a class defined by
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   543
         * {@link #defineProxyClass(Module, List)}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   544
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   545
        static boolean isProxyClass(Class<?> c) {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   546
            return Objects.equals(reverseProxyCache.sub(c).get(c.getClassLoader()),
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   547
                                  Boolean.TRUE);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   548
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   549
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   550
        private static boolean isExportedType(Class<?> c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   551
            String pn = c.getPackageName();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   552
            return Modifier.isPublic(c.getModifiers()) && c.getModule().isExported(pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   553
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   554
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   555
        private static boolean isPackagePrivateType(Class<?> c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   556
            return !Modifier.isPublic(c.getModifiers());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   557
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   558
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   559
        private static String toDetails(Class<?> c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   560
            String access = "unknown";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   561
            if (isExportedType(c)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   562
                access = "exported";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   563
            } else if (isPackagePrivateType(c)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   564
                access = "package-private";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   565
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   566
                access = "module-private";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   567
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   568
            ClassLoader ld = c.getClassLoader();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   569
            return String.format("   %s/%s %s loader %s",
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   570
                    c.getModule().getName(), c.getName(), access, ld);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   571
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   572
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   573
        static void trace(String cn, Module module, ClassLoader loader, List<Class<?>> interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   574
            if (isDebug()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   575
                System.out.format("PROXY: %s/%s defined by %s%n", module.getName(), cn, loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   576
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   577
            if (isDebug("debug")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   578
                interfaces.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   579
                          .forEach(c -> System.out.println(toDetails(c)));
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   580
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   581
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   582
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   583
        private static final String DEBUG =
37781
71ed5645f17c 8155775: Re-examine naming of privileged methods to access System properties
redestad
parents: 37593
diff changeset
   584
                GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   585
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   586
        private static boolean isDebug() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   587
            return !DEBUG.isEmpty();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   588
        }
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   589
        private static boolean isDebug(String flag) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   590
            return DEBUG.equals(flag);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   591
        }
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   592
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   593
        // ProxyBuilder instance members start here....
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   595
        private final ClassLoader loader;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   596
        private final List<Class<?>> interfaces;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   597
        private final Module module;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   598
        ProxyBuilder(ClassLoader loader, List<Class<?>> interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   599
            if (!VM.isModuleSystemInited()) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 40459
diff changeset
   600
                throw new InternalError("Proxy is not supported until module system is fully initialized");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   601
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   602
            if (interfaces.size() > 65535) {
41121
91734a3ed04b 8151832: Improve exception messages in exception thrown by new JDK 9 code
coffeys
parents: 40459
diff changeset
   603
                throw new IllegalArgumentException("interface limit exceeded: " + interfaces.size());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   604
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   605
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   606
            Set<Class<?>> refTypes = referencedTypes(loader, interfaces);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   607
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   608
            // IAE if violates any restrictions specified in newProxyInstance
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   609
            validateProxyInterfaces(loader, interfaces, refTypes);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   610
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   611
            this.loader = loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   612
            this.interfaces = interfaces;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   613
            this.module = mapToModule(loader, interfaces, refTypes);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   614
            assert getLoader(module) == loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   615
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   616
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   617
        ProxyBuilder(ClassLoader loader, Class<?> intf) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   618
            this(loader, Collections.singletonList(intf));
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   619
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   620
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   621
        /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   622
         * Generate a proxy class and return its proxy Constructor with
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   623
         * accessible flag already set. If the target module does not have access
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   624
         * to any interface types, IllegalAccessError will be thrown by the VM
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   625
         * at defineClass time.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   626
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   627
         * Must call the checkProxyAccess method to perform permission checks
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   628
         * before calling this.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   629
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   630
        Constructor<?> build() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   631
            Class<?> proxyClass = defineProxyClass(module, interfaces);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   632
            final Constructor<?> cons;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   633
            try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   634
                cons = proxyClass.getConstructor(constructorParams);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   635
            } catch (NoSuchMethodException e) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   636
                throw new InternalError(e.toString(), e);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   637
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   638
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   639
                public Void run() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   640
                    cons.setAccessible(true);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   641
                    return null;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   642
                }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   643
            });
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   644
            return cons;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   645
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   646
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   647
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   648
         * Validate the given proxy interfaces and the given referenced types
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   649
         * are visible to the defining loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   650
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   651
         * @throws IllegalArgumentException if it violates the restrictions specified
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   652
         *         in {@link Proxy#newProxyInstance}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   653
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   654
        private static void validateProxyInterfaces(ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   655
                                                    List<Class<?>> interfaces,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   656
                                                    Set<Class<?>> refTypes)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   657
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   658
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.size());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   659
            for (Class<?> intf : interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   660
                /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   661
                 * Verify that the class loader resolves the name of this
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   662
                 * interface to the same Class object.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   663
                 */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   664
                ensureVisible(loader, intf);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   665
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   666
                /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   667
                 * Verify that the Class object actually represents an
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   668
                 * interface.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   669
                 */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   670
                if (!intf.isInterface()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   671
                    throw new IllegalArgumentException(intf.getName() + " is not an interface");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   672
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   673
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   674
                /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   675
                 * Verify that this interface is not a duplicate.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   676
                 */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   677
                if (interfaceSet.put(intf, Boolean.TRUE) != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   678
                    throw new IllegalArgumentException("repeated interface: " + intf.getName());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   679
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   680
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   681
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   682
            for (Class<?> type : refTypes) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   683
                ensureVisible(loader, type);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   684
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   685
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   686
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   687
        /*
37349
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   688
         * Returns all types referenced by all public non-static method signatures of
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   689
         * the proxy interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   690
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   691
        private static Set<Class<?>> referencedTypes(ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   692
                                                     List<Class<?>> interfaces) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   693
            return interfaces.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   694
                 .flatMap(intf -> Stream.of(intf.getMethods())
37349
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   695
                                        .filter(m -> !Modifier.isStatic(m.getModifiers()))
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   696
                                        .flatMap(ProxyBuilder::methodRefTypes)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   697
                                        .map(ProxyBuilder::getElementType)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   698
                                        .filter(t -> !t.isPrimitive()))
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   699
                 .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   700
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   701
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   702
        /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   703
         * Extracts all types referenced on a method signature including
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   704
         * its return type, parameter types, and exception types.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   705
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   706
        private static Stream<Class<?>> methodRefTypes(Method m) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   707
            return Stream.of(new Class<?>[] { m.getReturnType() },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   708
                             m.getParameterTypes(),
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   709
                             m.getExceptionTypes())
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   710
                         .flatMap(Stream::of);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   711
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   712
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   713
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   714
         * Returns the module that the generated proxy class belongs to.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   715
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   716
         * If all proxy interfaces are public and in exported packages,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   717
         * then the proxy class is in unnamed module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   718
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   719
         * If any of proxy interface is package-private, then the proxy class
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   720
         * is in the same module of the package-private interface.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   721
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   722
         * If all proxy interfaces are public and at least one in a non-exported
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   723
         * package, then the proxy class is in a dynamic module in a non-exported
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   724
         * package.  Reads edge and qualified exports are added for
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   725
         * dynamic module to access.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   726
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   727
        private static Module mapToModule(ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   728
                                          List<Class<?>> interfaces,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   729
                                          Set<Class<?>> refTypes) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   730
            Map<Class<?>, Module> modulePrivateTypes = new HashMap<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   731
            Map<Class<?>, Module> packagePrivateTypes = new HashMap<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   732
            for (Class<?> intf : interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   733
                Module m = intf.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   734
                if (Modifier.isPublic(intf.getModifiers())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   735
                    // module-private types
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   736
                    if (!m.isExported(intf.getPackageName())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   737
                        modulePrivateTypes.put(intf, m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   738
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   739
                } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   740
                    packagePrivateTypes.put(intf, m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   741
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   742
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   743
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   744
            // all proxy interfaces are public and exported, the proxy class is in unnamed module
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   745
            // Such proxy class is accessible to any unnamed module and named module that
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   746
            // can read unnamed module
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   747
            if (packagePrivateTypes.isEmpty() && modulePrivateTypes.isEmpty()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   748
                return loader != null ? loader.getUnnamedModule() : BootLoader.getUnnamedModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   749
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   750
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   751
            if (packagePrivateTypes.size() > 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   752
                // all package-private types must be in the same runtime package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   753
                // i.e. same package name and same module (named or unnamed)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   754
                //
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   755
                // Configuration will fail if M1 and in M2 defined by the same loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   756
                // and both have the same package p (so no need to check class loader)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   757
                if (packagePrivateTypes.size() > 1 &&
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   758
                        (packagePrivateTypes.keySet().stream()  // more than one package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   759
                                 .map(Class::getPackageName).distinct().count() > 1 ||
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   760
                         packagePrivateTypes.values().stream()  // or more than one module
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   761
                                 .distinct().count() > 1)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   762
                    throw new IllegalArgumentException(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   763
                            "non-public interfaces from different packages");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   764
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   765
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   766
                // all package-private types are in the same module (named or unnamed)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   767
                Module target = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   768
                for (Module m : packagePrivateTypes.values()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   769
                    if (getLoader(m) != loader) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   770
                        // the specified loader is not the same class loader of the non-public interface
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   771
                        throw new IllegalArgumentException(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   772
                                "non-public interface is not defined by the given loader");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   773
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   774
                    target = m;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   775
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   776
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   777
                // validate if the target module can access all other interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   778
                for (Class<?> intf : interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   779
                    Module m = intf.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   780
                    if (m == target) continue;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   781
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   782
                    if (!target.canRead(m) || !m.isExported(intf.getPackageName(), target)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   783
                        throw new IllegalArgumentException(target + " can't access " + intf.getName());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   784
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   785
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   786
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   787
                // return the module of the package-private interface
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   788
                return target;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   789
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   790
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   791
            // all proxy interfaces are public and at least one in a non-exported package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   792
            // map to dynamic proxy module and add reads edge and qualified exports, if necessary
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   793
            Module target = getDynamicModule(loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   794
37349
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   795
            // set up proxy class access to proxy interfaces and types
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   796
            // referenced in the method signature
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   797
            Set<Class<?>> types = new HashSet<>(interfaces);
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   798
            types.addAll(refTypes);
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   799
            for (Class<?> c : types) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   800
                ensureAccess(target, c);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   801
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   802
            return target;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   803
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   804
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   805
        /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   806
         * Ensure the given module can access the given class.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   807
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   808
        private static void ensureAccess(Module target, Class<?> c) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   809
            Module m = c.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   810
            // add read edge and qualified export for the target module to access
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   811
            if (!target.canRead(m)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   812
                Modules.addReads(target, m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   813
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   814
            String pn = c.getPackageName();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   815
            if (!m.isExported(pn, target)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   816
                Modules.addExports(m, pn, target);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   817
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   818
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   819
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   820
        /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   821
         * Ensure the given class is visible to the class loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   822
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   823
        private static void ensureVisible(ClassLoader ld, Class<?> c) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   824
            Class<?> type = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   825
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   826
                type = Class.forName(c.getName(), false, ld);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   827
            } catch (ClassNotFoundException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   828
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   829
            if (type != c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   830
                throw new IllegalArgumentException(c.getName() +
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   831
                        " referenced from a method is not visible from class loader");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   832
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   833
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   834
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   835
        private static Class<?> getElementType(Class<?> type) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   836
            Class<?> e = type;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   837
            while (e.isArray()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   838
                e = e.getComponentType();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   839
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   840
            return e;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   841
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   842
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   843
        private static final ClassLoaderValue<Module> dynProxyModules =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   844
            new ClassLoaderValue<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   845
        private static final AtomicInteger counter = new AtomicInteger();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   846
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   847
        /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   848
         * Define a dynamic module for the generated proxy classes in a non-exported package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   849
         * named com.sun.proxy.$MODULE.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   850
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   851
         * Each class loader will have one dynamic module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   852
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   853
        private static Module getDynamicModule(ClassLoader loader) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   854
            return dynProxyModules.computeIfAbsent(loader, (ld, clv) -> {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   855
                // create a dynamic module and setup module access
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   856
                String mn = "jdk.proxy" + counter.incrementAndGet();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   857
                String pn = PROXY_PACKAGE_PREFIX + "." + mn;
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   858
                Module m = Modules.defineModule(ld, mn, Collections.singleton(pn));
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   859
                Modules.addReads(m, Proxy.class.getModule());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   860
                // java.base to create proxy instance
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   861
                Modules.addExports(m, pn, Object.class.getModule());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   862
                return m;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   863
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   864
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   865
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   866
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   867
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   868
     * Returns a proxy instance for the specified interfaces
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
     * that dispatches method invocations to the specified invocation
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   870
     * handler.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   871
     * <p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   872
     * <a name="restrictions">{@code IllegalArgumentException} will be thrown
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   873
     * if any of the following restrictions is violated:</a>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   874
     * <ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   875
     * <li>All of {@code Class} objects in the given {@code interfaces} array
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   876
     * must represent interfaces, not classes or primitive types.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   878
     * <li>No two elements in the {@code interfaces} array may
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   879
     * refer to identical {@code Class} objects.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   880
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   881
     * <li>All of the interface types must be visible by name through the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   882
     * specified class loader. In other words, for class loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   883
     * {@code cl} and every interface {@code i}, the following
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   884
     * expression must be true:<p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   885
     * {@code Class.forName(i.getName(), false, cl) == i}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   886
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   887
     * <li>All of the types referenced by all
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   888
     * public method signatures of the specified interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   889
     * and those inherited by their superinterfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   890
     * must be visible by name through the specified class loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   891
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   892
     * <li>All non-public interfaces must be in the same package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   893
     * and module, defined by the specified class loader and
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   894
     * the module of the non-public interfaces can access all of
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   895
     * the interface types; otherwise, it would not be possible for
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   896
     * the proxy class to implement all of the interfaces,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   897
     * regardless of what package it is defined in.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   898
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   899
     * <li>For any set of member methods of the specified interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   900
     * that have the same signature:
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   901
     * <ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   902
     * <li>If the return type of any of the methods is a primitive
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   903
     * type or void, then all of the methods must have that same
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   904
     * return type.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   905
     * <li>Otherwise, one of the methods must have a return type that
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   906
     * is assignable to all of the return types of the rest of the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   907
     * methods.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   908
     * </ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   909
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   910
     * <li>The resulting proxy class must not exceed any limits imposed
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   911
     * on classes by the virtual machine.  For example, the VM may limit
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   912
     * the number of interfaces that a class may implement to 65535; in
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   913
     * that case, the size of the {@code interfaces} array must not
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   914
     * exceed 65535.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   915
     * </ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   916
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   917
     * <p>Note that the order of the specified proxy interfaces is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   918
     * significant: two requests for a proxy class with the same combination
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   919
     * of interfaces but in a different order will result in two distinct
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   920
     * proxy classes.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
     * @param   loader the class loader to define the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
     * @param   interfaces the list of interfaces for the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
     *          to implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
     * @param   h the invocation handler to dispatch method invocations to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
     * @return  a proxy instance with the specified invocation handler of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
     *          proxy class that is defined by the specified class loader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
     *          and that implements the specified interfaces
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   929
     * @throws  IllegalArgumentException if any of the <a href="#restrictions">
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   930
     *          restrictions</a> on the parameters are violated
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   931
     * @throws  SecurityException if a security manager, <em>s</em>, is present
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   932
     *          and any of the following conditions is met:
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   933
     *          <ul>
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   934
     *          <li> the given {@code loader} is {@code null} and
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   935
     *               the caller's class loader is not {@code null} and the
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   936
     *               invocation of {@link SecurityManager#checkPermission
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   937
     *               s.checkPermission} with
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   938
     *               {@code RuntimePermission("getClassLoader")} permission
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   939
     *               denies access;</li>
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   940
     *          <li> for each proxy interface, {@code intf},
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   941
     *               the caller's class loader is not the same as or an
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   942
     *               ancestor of the class loader for {@code intf} and
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   943
     *               invocation of {@link SecurityManager#checkPackageAccess
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   944
     *               s.checkPackageAccess()} denies access to {@code intf};</li>
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   945
     *          <li> any of the given proxy interfaces is non-public and the
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   946
     *               caller class is not in the same {@linkplain Package runtime package}
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   947
     *               as the non-public interface and the invocation of
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   948
     *               {@link SecurityManager#checkPermission s.checkPermission} with
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   949
     *               {@code ReflectPermission("newProxyInPackage.{package name}")}
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   950
     *               permission denies access.</li>
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   951
     *          </ul>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     * @throws  NullPointerException if the {@code interfaces} array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     *          argument or any of its elements are {@code null}, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
     *          if the invocation handler, {@code h}, is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
     *          {@code null}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   956
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   957
     * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
     */
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   959
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
    public static Object newProxyInstance(ClassLoader loader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                                          Class<?>[] interfaces,
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   962
                                          InvocationHandler h) {
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   963
        Objects.requireNonNull(h);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   965
        final Class<?> caller = System.getSecurityManager() == null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   966
                                    ? null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   967
                                    : Reflection.getCallerClass();
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   968
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
        /*
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   970
         * Look up or generate the designated proxy class and its constructor.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   972
        Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   974
        return newProxyInstance(caller, cons, h);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   975
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   976
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   977
    private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   978
                                           Constructor<?> cons,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   979
                                           InvocationHandler h) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
         * Invoke its constructor with the designated invocation handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
        try {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   984
            if (caller != null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   985
                checkNewProxyPermission(caller, cons.getDeclaringClass());
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   986
            }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   987
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   988
            return cons.newInstance(new Object[]{h});
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   989
        } catch (IllegalAccessException | InstantiationException e) {
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   990
            throw new InternalError(e.toString(), e);
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   991
        } catch (InvocationTargetException e) {
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   992
            Throwable t = e.getCause();
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   993
            if (t instanceof RuntimeException) {
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   994
                throw (RuntimeException) t;
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   995
            } else {
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   996
                throw new InternalError(t.toString(), t);
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   997
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1001
    private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1002
        SecurityManager sm = System.getSecurityManager();
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1003
        if (sm != null) {
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1004
            if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1005
                ClassLoader ccl = caller.getClassLoader();
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1006
                ClassLoader pcl = proxyClass.getClassLoader();
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1007
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1008
                // do permission check if the caller is in a different runtime package
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1009
                // of the proxy class
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1010
                int n = proxyClass.getName().lastIndexOf('.');
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1011
                String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1012
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1013
                n = caller.getName().lastIndexOf('.');
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1014
                String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1015
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1016
                if (pcl != ccl || !pkg.equals(callerPkg)) {
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1017
                    sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1018
                }
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1019
            }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1020
        }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1021
    }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1022
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1024
     * Returns the class loader for the given module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1025
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1026
    private static ClassLoader getLoader(Module m) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1027
        PrivilegedAction<ClassLoader> pa = m::getClassLoader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1028
        return AccessController.doPrivileged(pa);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1029
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1030
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1031
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1032
     * Returns true if the given class is a proxy class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1034
     * @implNote The reliability of this method is important for the ability
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
     * to use it to make security decisions, so its implementation should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
     * not just test if the class in question extends {@code Proxy}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
     * @param   cl the class to test
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
     * @return  {@code true} if the class is a proxy class and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
     *          {@code false} otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
     * @throws  NullPointerException if {@code cl} is {@code null}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
    public static boolean isProxyClass(Class<?> cl) {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1044
        return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
     * Returns the invocation handler for the specified proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
     * @param   proxy the proxy instance to return the invocation handler for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
     * @return  the invocation handler for the proxy instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
     * @throws  IllegalArgumentException if the argument is not a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
     *          proxy instance
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1054
     * @throws  SecurityException if a security manager, <em>s</em>, is present
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1055
     *          and the caller's class loader is not the same as or an
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1056
     *          ancestor of the class loader for the invocation handler
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1057
     *          and invocation of {@link SecurityManager#checkPackageAccess
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1058
     *          s.checkPackageAccess()} denies access to the invocation
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1059
     *          handler's class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
     */
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1061
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
    public static InvocationHandler getInvocationHandler(Object proxy)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
        throws IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
         * Verify that the object is actually a proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
        if (!isProxyClass(proxy.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
            throw new IllegalArgumentException("not a proxy instance");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1072
        final Proxy p = (Proxy) proxy;
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1073
        final InvocationHandler ih = p.h;
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1074
        if (System.getSecurityManager() != null) {
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1075
            Class<?> ihClass = ih.getClass();
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1076
            Class<?> caller = Reflection.getCallerClass();
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1077
            if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1078
                                                    ihClass.getClassLoader()))
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1079
            {
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1080
                ReflectUtil.checkPackageAccess(ihClass);
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1081
            }
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1082
        }
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1083
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1084
        return ih;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1087
    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1088
    private static final String PROXY_PACKAGE_PREFIX = ReflectUtil.PROXY_PACKAGE;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
}