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