src/java.base/share/classes/java/lang/reflect/Proxy.java
author mchung
Wed, 08 Nov 2017 13:38:00 -0800
changeset 47722 ce6ff74192fc
parent 47216 71c04702a3d5
child 49273 af8ab4f90a32
permissions -rw-r--r--
8190733: Use Class::getPackageName in java.base implementation Reviewed-by: mchung, rriggs Contributed-by: Christoph Dreis <christoph.dreis@freenet.de>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
     2
 * Copyright (c) 1999, 2017, 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
import java.util.stream.Collectors;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    43
import java.util.stream.Stream;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
    44
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;
36669
17af8b44d311 8152642: Remove sun.misc.Unsafe dependency from java.lang.reflect.Proxy
chegar
parents: 36511
diff changeset
    47
import jdk.internal.misc.Unsafe;
34882
ce2a8ec851c1 8145544: Move sun.misc.VM to jdk.internal.misc
chegar
parents: 34704
diff changeset
    48
import jdk.internal.misc.VM;
37363
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 37349
diff changeset
    49
import jdk.internal.reflect.CallerSensitive;
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 37349
diff changeset
    50
import jdk.internal.reflect.Reflection;
40459
88a91142b711 8164547: Make java.lang.reflect.ClassLoaderValue public for internal use
plevart
parents: 37781
diff changeset
    51
import jdk.internal.loader.ClassLoaderValue;
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
    52
import sun.reflect.misc.ReflectUtil;
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
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   103
 * creation, in the same order. Invoking {@link Class#getInterfaces getInterfaces}
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
 *
44844
b2b4d98404ba 8179364: update "<a name=" in java.base module to use id attribute
jjg
parents: 44545
diff changeset
   160
 * <h3><a id="membership">Package and Module Membership of Proxy Class</a></h3>
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 {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    private static final long serialVersionUID = -2222568056686623797L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    /** parameter types of a proxy class constructor */
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   289
    private static final Class<?>[] constructorParams =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        { InvocationHandler.class };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   292
    /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   293
     * a cache of proxy constructors with
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   294
     * {@link Constructor#setAccessible(boolean) accessible} flag already set
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   295
     */
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   296
    private static final ClassLoaderValue<Constructor<?>> proxyCache =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   297
        new ClassLoaderValue<>();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   298
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   299
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * the invocation handler for this proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * @serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    protected InvocationHandler h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * Prohibits instantiation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    private Proxy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * Constructs a new {@code Proxy} instance from a subclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * (typically, a dynamic proxy class) with the specified value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * for its invocation handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     *
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   316
     * @param  h the invocation handler for this proxy instance
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   317
     *
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   318
     * @throws NullPointerException if the given invocation handler, {@code h},
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   319
     *         is {@code null}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    protected Proxy(InvocationHandler h) {
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   322
        Objects.requireNonNull(h);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        this.h = h;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * Returns the {@code java.lang.Class} object for a proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * given a class loader and an array of interfaces.  The proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * 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
   330
     * 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
   331
     * 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
   332
     * 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
   333
     * class loader, then the existing proxy class will be returned; otherwise,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * a proxy class for those interfaces will be generated dynamically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     * and defined by the class loader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
     * @param   loader the class loader to define the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * @param   interfaces the list of interfaces for the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     *          to implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * @return  a proxy class that is defined in the specified class loader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     *          and that implements the specified interfaces
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   342
     * @throws  IllegalArgumentException if any of the <a href="#restrictions">
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   343
     *          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
   344
     * @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
   345
     *          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
   346
     *          <ul>
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   347
     *             <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
   348
     *             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
   349
     *             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
   350
     *             s.checkPermission} with
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   351
     *             {@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
   352
     *             denies access.</li>
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   353
     *             <li> for each proxy interface, {@code intf},
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   354
     *             the caller's class loader is not the same as or an
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   355
     *             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
   356
     *             invocation of {@link SecurityManager#checkPackageAccess
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   357
     *             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
   358
     *          </ul>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * @throws  NullPointerException if the {@code interfaces} array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     *          argument or any of its elements are {@code null}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   361
     *
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   362
     * @deprecated Proxy classes generated in a named module are encapsulated
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   363
     *      and not accessible to code outside its module.
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   364
     *      {@link Constructor#newInstance(Object...) Constructor.newInstance}
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   365
     *      will throw {@code IllegalAccessException} when it is called on
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   366
     *      an inaccessible proxy class.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   367
     *      Use {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   368
     *      to create a proxy instance instead.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   369
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   370
     * @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
   371
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   372
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     */
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   374
    @Deprecated
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   375
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    public static Class<?> getProxyClass(ClassLoader loader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                                         Class<?>... interfaces)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        throws IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   380
        Class<?> caller = System.getSecurityManager() == null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   381
                              ? null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   382
                              : Reflection.getCallerClass();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   383
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   384
        return getProxyConstructor(caller, loader, interfaces)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   385
            .getDeclaringClass();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   386
    }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   387
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   388
    /**
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   389
     * 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
   390
     * single argument of type {@link InvocationHandler}, given a class loader
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   391
     * 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
   392
     * {@link Constructor#setAccessible(boolean) accessible} flag already set.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   393
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   394
     * @param   caller passed from a public-facing @CallerSensitive method if
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   395
     *                 SecurityManager is set or {@code null} if there's no
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   396
     *                 SecurityManager
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   397
     * @param   loader the class loader to define the proxy class
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   398
     * @param   interfaces the list of interfaces for the proxy class
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   399
     *          to implement
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   400
     * @return  a Constructor of the proxy class taking single
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   401
     *          {@code InvocationHandler} parameter
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
    private static Constructor<?> getProxyConstructor(Class<?> caller,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   404
                                                      ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   405
                                                      Class<?>... interfaces)
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   406
    {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   407
        // optimization for single interface
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   408
        if (interfaces.length == 1) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   409
            Class<?> intf = interfaces[0];
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   410
            if (caller != null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   411
                checkProxyAccess(caller, loader, intf);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   412
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   413
            return proxyCache.sub(intf).computeIfAbsent(
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   414
                loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   415
                (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   416
            );
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   417
        } else {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   418
            // interfaces cloned
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   419
            final Class<?>[] intfsArray = interfaces.clone();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   420
            if (caller != null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   421
                checkProxyAccess(caller, loader, intfsArray);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   422
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   423
            final List<Class<?>> intfs = Arrays.asList(intfsArray);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   424
            return proxyCache.sub(intfs).computeIfAbsent(
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   425
                loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   426
                (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   427
            );
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   428
        }
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   429
    }
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   430
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   431
    /*
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   432
     * Check permissions required to create a Proxy class.
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   433
     *
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   434
     * 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
   435
     * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   436
     * 1. "getClassLoader" permission check if loader == null
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   437
     * 2. checkPackageAccess on the interfaces it implements
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
     * 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
   440
     * the package access check on the interfaces it implements
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   441
     * as in Class.getConstructor.
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
     * 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
   444
     * 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
   445
     * 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
   446
     * will throw IllegalAccessError when the generated proxy class is
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   447
     * being defined.
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   448
     */
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   449
    private static void checkProxyAccess(Class<?> caller,
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   450
                                         ClassLoader loader,
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   451
                                         Class<?> ... interfaces)
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   452
    {
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   453
        SecurityManager sm = System.getSecurityManager();
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   454
        if (sm != null) {
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   455
            ClassLoader ccl = caller.getClassLoader();
46047
97d615d81827 8161121: VM::isSystemDomainLoader should consider platform class loader
mchung
parents: 44844
diff changeset
   456
            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
   457
                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   458
            }
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   459
            ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   460
        }
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   461
    }
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   462
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   463
    /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   464
     * Builder for a proxy class.
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   465
     *
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   466
     * If the module is not specified in this ProxyBuilder constructor,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   467
     * 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
   468
     * 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
   469
     */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   470
    private static final class ProxyBuilder {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   471
        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   472
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   473
        // prefix for all proxy class names
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   474
        private static final String proxyClassNamePrefix = "$Proxy";
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   475
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   476
        // 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
   477
        private static final AtomicLong nextUniqueNumber = new AtomicLong();
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
        // a reverse cache of defined proxy classes
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   480
        private static final ClassLoaderValue<Boolean> reverseProxyCache =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   481
            new ClassLoaderValue<>();
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   482
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   483
        private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
            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
   485
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
             * Record the package of a non-public proxy interface so that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
             * proxy class will be defined in the same package.  Verify that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
             * all non-public proxy interfaces are in the same package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
             */
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   492
            for (Class<?> intf : interfaces) {
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   493
                int flags = intf.getModifiers();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                if (!Modifier.isPublic(flags)) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   495
                    accessFlags = Modifier.FINAL;  // non-public, final
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   496
                    String pkg = intf.getPackageName();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                    if (proxyPkg == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                        proxyPkg = pkg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                    } else if (!pkg.equals(proxyPkg)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                        throw new IllegalArgumentException(
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   501
                                "non-public interfaces from different packages");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
   506
            if (proxyPkg == null) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   507
                // all proxy interfaces are public
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   508
                proxyPkg = m.isNamed() ? PROXY_PACKAGE_PREFIX + "." + m.getName()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   509
                                       : PROXY_PACKAGE_PREFIX;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   510
            } else if (proxyPkg.isEmpty() && m.isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   511
                throw new IllegalArgumentException(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   512
                        "Unnamed package cannot be added to " + m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   513
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   514
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   515
            if (m.isNamed()) {
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   516
                if (!m.getDescriptor().packages().contains(proxyPkg)) {
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   517
                    throw new InternalError(proxyPkg + " not exist in " + m.getName());
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   518
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   521
            /*
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   522
             * 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
   523
             */
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   524
            long num = nextUniqueNumber.getAndIncrement();
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   525
            String proxyName = proxyPkg.isEmpty()
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   526
                                    ? proxyClassNamePrefix + num
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   527
                                    : proxyPkg + "." + proxyClassNamePrefix + num;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   528
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   529
            ClassLoader loader = getLoader(m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   530
            trace(proxyName, m, loader, interfaces);
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   531
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
             * Generate the specified proxy class.
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   534
             */
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   535
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   536
                    proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   537
            try {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   538
                Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   539
                                                 0, proxyClassFile.length,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   540
                                                 loader, null);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   541
                reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   542
                return pc;
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   543
            } catch (ClassFormatError e) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                /*
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   545
                 * 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
   546
                 * proxy class generation code) there was some other
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   547
                 * 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
   548
                 * class creation (such as virtual machine limitations
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   549
                 * exceeded).
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                 */
17188
5e58e261911b 7123493: (proxy) Proxy.getProxyClass doesn't scale under high load
plevart
parents: 16923
diff changeset
   551
                throw new IllegalArgumentException(e.toString());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   554
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   555
        /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   556
         * Test if given class is a class defined by
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   557
         * {@link #defineProxyClass(Module, List)}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   558
         */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   559
        static boolean isProxyClass(Class<?> c) {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   560
            return Objects.equals(reverseProxyCache.sub(c).get(c.getClassLoader()),
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   561
                                  Boolean.TRUE);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   562
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   563
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   564
        private static boolean isExportedType(Class<?> c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   565
            String pn = c.getPackageName();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   566
            return Modifier.isPublic(c.getModifiers()) && c.getModule().isExported(pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   567
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   568
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   569
        private static boolean isPackagePrivateType(Class<?> c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   570
            return !Modifier.isPublic(c.getModifiers());
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 String toDetails(Class<?> c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   574
            String access = "unknown";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   575
            if (isExportedType(c)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   576
                access = "exported";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   577
            } else if (isPackagePrivateType(c)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   578
                access = "package-private";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   579
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   580
                access = "module-private";
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   581
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   582
            ClassLoader ld = c.getClassLoader();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   583
            return String.format("   %s/%s %s loader %s",
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   584
                    c.getModule().getName(), c.getName(), access, ld);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   585
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   586
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   587
        static void trace(String cn,
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   588
                          Module module,
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   589
                          ClassLoader loader,
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   590
                          List<Class<?>> interfaces) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   591
            if (isDebug()) {
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   592
                System.err.format("PROXY: %s/%s defined by %s%n",
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   593
                                  module.getName(), cn, loader);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   594
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   595
            if (isDebug("debug")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   596
                interfaces.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   597
                          .forEach(c -> System.out.println(toDetails(c)));
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   598
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   599
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   600
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   601
        private static final String DEBUG =
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   602
            GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   603
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   604
        private static boolean isDebug() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   605
            return !DEBUG.isEmpty();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   606
        }
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   607
        private static boolean isDebug(String flag) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   608
            return DEBUG.equals(flag);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   609
        }
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   610
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   611
        // ProxyBuilder instance members start here....
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   613
        private final List<Class<?>> interfaces;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   614
        private final Module module;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   615
        ProxyBuilder(ClassLoader loader, List<Class<?>> interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   616
            if (!VM.isModuleSystemInited()) {
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   617
                throw new InternalError("Proxy is not supported until "
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   618
                        + "module system is fully initialized");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   619
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   620
            if (interfaces.size() > 65535) {
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   621
                throw new IllegalArgumentException("interface limit exceeded: "
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   622
                        + interfaces.size());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   623
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   624
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   625
            Set<Class<?>> refTypes = referencedTypes(loader, interfaces);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   626
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   627
            // IAE if violates any restrictions specified in newProxyInstance
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   628
            validateProxyInterfaces(loader, interfaces, refTypes);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   629
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   630
            this.interfaces = interfaces;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   631
            this.module = mapToModule(loader, interfaces, refTypes);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   632
            assert getLoader(module) == loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   633
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   634
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   635
        ProxyBuilder(ClassLoader loader, Class<?> intf) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   636
            this(loader, Collections.singletonList(intf));
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   637
        }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   638
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   639
        /**
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   640
         * Generate a proxy class and return its proxy Constructor with
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   641
         * accessible flag already set. If the target module does not have access
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   642
         * to any interface types, IllegalAccessError will be thrown by the VM
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   643
         * at defineClass time.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   644
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   645
         * Must call the checkProxyAccess method to perform permission checks
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   646
         * before calling this.
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
        Constructor<?> build() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   649
            Class<?> proxyClass = defineProxyClass(module, interfaces);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   650
            final Constructor<?> cons;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   651
            try {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   652
                cons = proxyClass.getConstructor(constructorParams);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   653
            } catch (NoSuchMethodException e) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   654
                throw new InternalError(e.toString(), e);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   655
            }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   656
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   657
                public Void run() {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   658
                    cons.setAccessible(true);
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   659
                    return null;
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   660
                }
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   661
            });
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   662
            return cons;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   663
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   664
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   665
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   666
         * Validate the given proxy interfaces and the given referenced types
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   667
         * are visible to the defining loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   668
         *
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   669
         * @throws IllegalArgumentException if it violates the restrictions
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   670
         *         specified in {@link Proxy#newProxyInstance}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   671
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   672
        private static void validateProxyInterfaces(ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   673
                                                    List<Class<?>> interfaces,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   674
                                                    Set<Class<?>> refTypes)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   675
        {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   676
            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.size());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   677
            for (Class<?> intf : interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   678
                /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   679
                 * Verify that the class loader resolves the name of this
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   680
                 * interface to the same Class object.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   681
                 */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   682
                ensureVisible(loader, intf);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   683
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   684
                /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   685
                 * Verify that the Class object actually represents an
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   686
                 * interface.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   687
                 */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   688
                if (!intf.isInterface()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   689
                    throw new IllegalArgumentException(intf.getName() + " is not an interface");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   690
                }
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 this interface is not a duplicate.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   694
                 */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   695
                if (interfaceSet.put(intf, Boolean.TRUE) != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   696
                    throw new IllegalArgumentException("repeated interface: " + intf.getName());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   697
                }
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
            for (Class<?> type : refTypes) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   701
                ensureVisible(loader, type);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   702
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   703
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   704
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   705
        /*
37349
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   706
         * Returns all types referenced by all public non-static method signatures of
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   707
         * the proxy interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   708
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   709
        private static Set<Class<?>> referencedTypes(ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   710
                                                     List<Class<?>> interfaces) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   711
            return interfaces.stream()
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   712
                 .flatMap(intf -> Stream.of(intf.getMethods())
37349
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   713
                                        .filter(m -> !Modifier.isStatic(m.getModifiers()))
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   714
                                        .flatMap(ProxyBuilder::methodRefTypes)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   715
                                        .map(ProxyBuilder::getElementType)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   716
                                        .filter(t -> !t.isPrimitive()))
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   717
                 .collect(Collectors.toSet());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   718
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   719
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   720
        /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   721
         * Extracts all types referenced on a method signature including
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   722
         * its return type, parameter types, and exception types.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   723
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   724
        private static Stream<Class<?>> methodRefTypes(Method m) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   725
            return Stream.of(new Class<?>[] { m.getReturnType() },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   726
                             m.getParameterTypes(),
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   727
                             m.getExceptionTypes())
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   728
                         .flatMap(Stream::of);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   729
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   730
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   731
        /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   732
         * Returns the module that the generated proxy class belongs to.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   733
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   734
         * If all proxy interfaces are public and in exported packages,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   735
         * then the proxy class is in unnamed module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   736
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   737
         * If any of proxy interface is package-private, then the proxy class
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   738
         * is in the same module of the package-private interface.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   739
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   740
         * 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
   741
         * 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
   742
         * non-exported package.  Reads edge and qualified exports are added
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   743
         * for dynamic module to access.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   744
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   745
        private static Module mapToModule(ClassLoader loader,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   746
                                          List<Class<?>> interfaces,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   747
                                          Set<Class<?>> refTypes) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   748
            Map<Class<?>, Module> modulePrivateTypes = new HashMap<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   749
            Map<Class<?>, Module> packagePrivateTypes = new HashMap<>();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   750
            for (Class<?> intf : interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   751
                Module m = intf.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   752
                if (Modifier.isPublic(intf.getModifiers())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   753
                    // module-private types
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   754
                    if (!m.isExported(intf.getPackageName())) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   755
                        modulePrivateTypes.put(intf, m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   756
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   757
                } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   758
                    packagePrivateTypes.put(intf, m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   759
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   760
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   761
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   762
            // all proxy interfaces are public and exported, the proxy class
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   763
            // is in unnamed module.  Such proxy class is accessible to
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   764
            // any unnamed module and named module that can read unnamed module
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   765
            if (packagePrivateTypes.isEmpty() && modulePrivateTypes.isEmpty()) {
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   766
                return loader != null ? loader.getUnnamedModule()
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   767
                                      : BootLoader.getUnnamedModule();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   768
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   769
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   770
            if (packagePrivateTypes.size() > 0) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   771
                // all package-private types must be in the same runtime package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   772
                // i.e. same package name and same module (named or unnamed)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   773
                //
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   774
                // Configuration will fail if M1 and in M2 defined by the same loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   775
                // and both have the same package p (so no need to check class loader)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   776
                if (packagePrivateTypes.size() > 1 &&
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   777
                        (packagePrivateTypes.keySet().stream()  // more than one package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   778
                                 .map(Class::getPackageName).distinct().count() > 1 ||
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   779
                         packagePrivateTypes.values().stream()  // or more than one module
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   780
                                 .distinct().count() > 1)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   781
                    throw new IllegalArgumentException(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   782
                            "non-public interfaces from different packages");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   783
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   784
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   785
                // all package-private types are in the same module (named or unnamed)
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   786
                Module target = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   787
                for (Module m : packagePrivateTypes.values()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   788
                    if (getLoader(m) != loader) {
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   789
                        // the specified loader is not the same class loader
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   790
                        // of the non-public interface
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   791
                        throw new IllegalArgumentException(
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   792
                                "non-public interface is not defined by the given loader");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   793
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   794
                    target = m;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   795
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   796
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   797
                // validate if the target module can access all other interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   798
                for (Class<?> intf : interfaces) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   799
                    Module m = intf.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   800
                    if (m == target) continue;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   801
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   802
                    if (!target.canRead(m) || !m.isExported(intf.getPackageName(), target)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   803
                        throw new IllegalArgumentException(target + " can't access " + intf.getName());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   804
                    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   805
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   806
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   807
                // return the module of the package-private interface
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   808
                return target;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   809
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   810
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   811
            // 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
   812
            // 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
   813
            // and qualified exports, if necessary
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   814
            Module target = getDynamicModule(loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   815
37349
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   816
            // 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
   817
            // referenced in the method signature
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   818
            Set<Class<?>> types = new HashSet<>(interfaces);
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   819
            types.addAll(refTypes);
648609dc0f3d 8153895: (proxy) redundant read edges to superinterfaces of proxy interfaces
mchung
parents: 36972
diff changeset
   820
            for (Class<?> c : types) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   821
                ensureAccess(target, c);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   822
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   823
            return target;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   824
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   825
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   826
        /*
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   827
         * Ensure the given module can access the given class.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   828
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   829
        private static void ensureAccess(Module target, Class<?> c) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   830
            Module m = c.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   831
            // add read edge and qualified export for the target module to access
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   832
            if (!target.canRead(m)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   833
                Modules.addReads(target, m);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   834
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   835
            String pn = c.getPackageName();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   836
            if (!m.isExported(pn, target)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   837
                Modules.addExports(m, pn, target);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   838
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   839
        }
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
         * Ensure the given class is visible to the class loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   843
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   844
        private static void ensureVisible(ClassLoader ld, Class<?> c) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   845
            Class<?> type = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   846
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   847
                type = Class.forName(c.getName(), false, ld);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   848
            } catch (ClassNotFoundException e) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   849
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   850
            if (type != c) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   851
                throw new IllegalArgumentException(c.getName() +
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   852
                        " referenced from a method is not visible from class loader");
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   853
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   854
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   855
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   856
        private static Class<?> getElementType(Class<?> type) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   857
            Class<?> e = type;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   858
            while (e.isArray()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   859
                e = e.getComponentType();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   860
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   861
            return e;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   862
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   863
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   864
        private static final ClassLoaderValue<Module> dynProxyModules =
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   865
            new ClassLoaderValue<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   866
        private static final AtomicInteger counter = new AtomicInteger();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   867
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   868
        /*
44359
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   869
         * Define a dynamic module for the generated proxy classes in
c6761862ca0b 8174823: Module system implementation refresh (3/2017)
alanb
parents: 43712
diff changeset
   870
         * a non-exported package named com.sun.proxy.$MODULE.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   871
         *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   872
         * Each class loader will have one dynamic module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   873
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   874
        private static Module getDynamicModule(ClassLoader loader) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   875
            return dynProxyModules.computeIfAbsent(loader, (ld, clv) -> {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   876
                // create a dynamic module and setup module access
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   877
                String mn = "jdk.proxy" + counter.incrementAndGet();
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   878
                String pn = PROXY_PACKAGE_PREFIX + "." + mn;
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   879
                ModuleDescriptor descriptor =
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   880
                    ModuleDescriptor.newModule(mn, Set.of(SYNTHETIC))
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   881
                                    .packages(Set.of(pn))
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   882
                                    .build();
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   883
                Module m = Modules.defineModule(ld, descriptor, null);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   884
                Modules.addReads(m, Proxy.class.getModule());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   885
                // java.base to create proxy instance
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   886
                Modules.addExports(m, pn, Object.class.getModule());
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   887
                return m;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   888
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   889
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   890
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   891
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   892
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   893
     * Returns a proxy instance for the specified interfaces
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
     * 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
   895
     * handler.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   896
     * <p>
44844
b2b4d98404ba 8179364: update "<a name=" in java.base module to use id attribute
jjg
parents: 44545
diff changeset
   897
     * <a id="restrictions">{@code IllegalArgumentException} will be thrown
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   898
     * if any of the following restrictions is violated:</a>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   899
     * <ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   900
     * <li>All of {@code Class} objects in the given {@code interfaces} array
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   901
     * must represent interfaces, not classes or primitive types.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   903
     * <li>No two elements in the {@code interfaces} array may
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   904
     * refer to identical {@code Class} objects.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   905
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   906
     * <li>All of the interface types must be visible by name through the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   907
     * specified class loader. In other words, for class loader
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   908
     * {@code cl} and every interface {@code i}, the following
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   909
     * expression must be true:<p>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   910
     * {@code Class.forName(i.getName(), false, cl) == i}
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   911
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   912
     * <li>All of the types referenced by all
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   913
     * public method signatures of the specified interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   914
     * and those inherited by their superinterfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   915
     * must be visible by name through the specified class loader.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   916
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   917
     * <li>All non-public interfaces must be in the same package
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   918
     * and module, defined by the specified class loader and
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   919
     * the module of the non-public interfaces can access all of
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   920
     * the interface types; otherwise, it would not be possible for
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   921
     * the proxy class to implement all of the interfaces,
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   922
     * regardless of what package it is defined in.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   923
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   924
     * <li>For any set of member methods of the specified interfaces
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   925
     * that have the same signature:
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   926
     * <ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   927
     * <li>If the return type of any of the methods is a primitive
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   928
     * type or void, then all of the methods must have that same
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   929
     * return type.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   930
     * <li>Otherwise, one of the methods must have a return type that
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   931
     * is assignable to all of the return types of the rest of the
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   932
     * methods.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   933
     * </ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   934
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   935
     * <li>The resulting proxy class must not exceed any limits imposed
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   936
     * on classes by the virtual machine.  For example, the VM may limit
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   937
     * the number of interfaces that a class may implement to 65535; in
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   938
     * that case, the size of the {@code interfaces} array must not
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   939
     * exceed 65535.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   940
     * </ul>
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   941
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   942
     * <p>Note that the order of the specified proxy interfaces is
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   943
     * significant: two requests for a proxy class with the same combination
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   944
     * of interfaces but in a different order will result in two distinct
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   945
     * proxy classes.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
     * @param   loader the class loader to define the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
     * @param   interfaces the list of interfaces for the proxy class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
     *          to implement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
     * @param   h the invocation handler to dispatch method invocations to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
     * @return  a proxy instance with the specified invocation handler of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     *          proxy class that is defined by the specified class loader
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     *          and that implements the specified interfaces
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   954
     * @throws  IllegalArgumentException if any of the <a href="#restrictions">
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   955
     *          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
   956
     * @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
   957
     *          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
   958
     *          <ul>
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   959
     *          <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
   960
     *               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
   961
     *               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
   962
     *               s.checkPermission} with
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
   963
     *               {@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
   964
     *               denies access;</li>
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   965
     *          <li> for each proxy interface, {@code intf},
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   966
     *               the caller's class loader is not the same as or an
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   967
     *               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
   968
     *               invocation of {@link SecurityManager#checkPackageAccess
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
   969
     *               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
   970
     *          <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
   971
     *               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
   972
     *               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
   973
     *               {@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
   974
     *               {@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
   975
     *               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
   976
     *          </ul>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
     * @throws  NullPointerException if the {@code interfaces} array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
     *          argument or any of its elements are {@code null}, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
     *          if the invocation handler, {@code h}, is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
     *          {@code null}
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   981
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   982
     * @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
   983
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
   984
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
     */
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   986
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    public static Object newProxyInstance(ClassLoader loader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                                          Class<?>[] interfaces,
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
   989
                                          InvocationHandler h) {
17497
e65d73b7ae54 4487672: (proxy) Proxy constructor should check for null argument
mchung
parents: 17188
diff changeset
   990
        Objects.requireNonNull(h);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   992
        final Class<?> caller = System.getSecurityManager() == null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   993
                                    ? null
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   994
                                    : Reflection.getCallerClass();
16906
44dfee24cb71 8010117: Annotate jdk caller sensitive methods with @sun.reflect.CallerSensitive
mchung
parents: 16108
diff changeset
   995
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        /*
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   997
         * Look up or generate the designated proxy class and its constructor.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
         */
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
   999
        Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1001
        return newProxyInstance(caller, cons, h);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1002
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1003
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1004
    private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1005
                                           Constructor<?> cons,
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1006
                                           InvocationHandler h) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
         * Invoke its constructor with the designated invocation handler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        try {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1011
            if (caller != null) {
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1012
                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
  1013
            }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1014
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1015
            return cons.newInstance(new Object[]{h});
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1016
        } 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
  1017
            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
  1018
        } catch (InvocationTargetException e) {
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1019
            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
  1020
            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
  1021
                throw (RuntimeException) t;
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
  1022
            } else {
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1023
                throw new InternalError(t.toString(), t);
16087
89b565a23835 7197546: (proxy) Reflect about creating reflective proxies
mchung
parents: 10419
diff changeset
  1024
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1028
    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
  1029
        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
  1030
        if (sm != null) {
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1031
            if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1032
                ClassLoader ccl = caller.getClassLoader();
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1033
                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
  1034
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1035
                // do permission check if the caller is in a different runtime package
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1036
                // of the proxy class
47722
ce6ff74192fc 8190733: Use Class::getPackageName in java.base implementation
mchung
parents: 47216
diff changeset
  1037
                String pkg = proxyClass.getPackageName();
ce6ff74192fc 8190733: Use Class::getPackageName in java.base implementation
mchung
parents: 47216
diff changeset
  1038
                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
  1039
18244
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1040
                if (pcl != ccl || !pkg.equals(callerPkg)) {
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1041
                    sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
a1031f4526b2 8011557: Improve reflection utility classes
mchung
parents: 16923
diff changeset
  1042
                }
16923
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1043
            }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1044
        }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1045
    }
50bfa0defec2 8004260: dynamic proxy class should have the same Java language access as the proxy interfaces
mchung
parents: 16906
diff changeset
  1046
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
    /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1048
     * Returns the class loader for the given module.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1049
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1050
    private static ClassLoader getLoader(Module m) {
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1051
        PrivilegedAction<ClassLoader> pa = m::getClassLoader;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1052
        return AccessController.doPrivileged(pa);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1053
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1054
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1055
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1056
     * Returns true if the given class is a proxy class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1058
     * @implNote The reliability of this method is important for the ability
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
     * to use it to make security decisions, so its implementation should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
     * not just test if the class in question extends {@code Proxy}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
     * @param   cl the class to test
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
     * @return  {@code true} if the class is a proxy class and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
     *          {@code false} otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
     * @throws  NullPointerException if {@code cl} is {@code null}
43712
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
  1066
     *
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
  1067
     * @revised 9
5dfd0950317c 8173393: Module system implementation refresh (2/2017)
alanb
parents: 41121
diff changeset
  1068
     * @spec JPMS
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
    public static boolean isProxyClass(Class<?> cl) {
36972
27147cde3256 8152115: (proxy) Examine performance of dynamic proxy creation
plevart
parents: 36669
diff changeset
  1071
        return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
     * Returns the invocation handler for the specified proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
     * @param   proxy the proxy instance to return the invocation handler for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
     * @return  the invocation handler for the proxy instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
     * @throws  IllegalArgumentException if the argument is not a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
     *          proxy instance
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1081
     * @throws  SecurityException if a security manager, <em>s</em>, is present
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1082
     *          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
  1083
     *          ancestor of the class loader for the invocation handler
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1084
     *          and invocation of {@link SecurityManager#checkPackageAccess
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1085
     *          s.checkPackageAccess()} denies access to the invocation
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1086
     *          handler's class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
     */
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1088
    @CallerSensitive
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
    public static InvocationHandler getInvocationHandler(Object proxy)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
        throws IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
         * Verify that the object is actually a proxy instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
        if (!isProxyClass(proxy.getClass())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
            throw new IllegalArgumentException("not a proxy instance");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
20825
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1099
        final Proxy p = (Proxy) proxy;
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1100
        final InvocationHandler ih = p.h;
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1101
        if (System.getSecurityManager() != null) {
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1102
            Class<?> ihClass = ih.getClass();
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1103
            Class<?> caller = Reflection.getCallerClass();
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1104
            if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1105
                                                    ihClass.getClassLoader()))
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1106
            {
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1107
                ReflectUtil.checkPackageAccess(ihClass);
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1108
            }
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1109
        }
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1110
3d5429b4b601 8017196: Ensure Proxies are handled appropriately
mchung
parents: 18251
diff changeset
  1111
        return ih;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1114
    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
9d0388c6b336 8142968: Module System implementation
alanb
parents: 34882
diff changeset
  1115
    private static final String PROXY_PACKAGE_PREFIX = ReflectUtil.PROXY_PACKAGE;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
}