< prev index next >
src/java.base/share/classes/java/lang/reflect/Proxy.java
Print this page
*** 23,33 ****
* questions.
*/
package java.lang.reflect;
- import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
--- 23,32 ----
*** 37,50 ****
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
- import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
- import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.loader.BootLoader;
import jdk.internal.module.Modules;
--- 36,47 ----
*** 282,291 ****
--- 279,295 ----
/** parameter types of a proxy class constructor */
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
/**
+ * a cache of proxy constructors with
+ * {@link Constructor#setAccessible(boolean) accessible} flag already set
+ */
+ private static final ClassLoaderValue<Constructor<?>> proxyCache =
+ new ClassLoaderValue<>();
+
+ /**
* the invocation handler for this proxy instance.
* @serial
*/
protected InvocationHandler h;
*** 359,376 ****
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
! final List<Class<?>> intfs = List.of(interfaces); // interfaces cloned
! final SecurityManager sm = System.getSecurityManager();
! final Class<?> caller = Reflection.getCallerClass();
! if (sm != null) {
! checkProxyAccess(caller, loader, intfs);
}
! return new ProxyBuilder(loader, intfs).build();
}
/*
* Check permissions required to create a Proxy class.
*
--- 363,407 ----
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
! Class<?> caller = System.getSecurityManager() == null
! ? null
! : Reflection.getCallerClass();
!
! return getProxyConstructor(caller, loader, interfaces)
! .getDeclaringClass();
}
! private static Constructor<?> getProxyConstructor(Class<?> caller, // null if no SecurityManager
! ClassLoader loader,
! Class<?>... interfaces)
! throws IllegalArgumentException
! {
! // optimization for single interface
! if (interfaces.length == 1) {
! Class<?> intf = interfaces[0];
! if (caller != null) {
! checkProxyAccess(caller, loader, intf);
! }
! return proxyCache.sub(intf).computeIfAbsent(
! loader,
! (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
! );
! } else {
! // interfaces cloned
! final Class<?>[] intfsArray = interfaces.clone();
! if (caller != null) {
! checkProxyAccess(caller, loader, intfsArray);
! }
! final List<Class<?>> intfs = Arrays.asList(intfsArray);
! return proxyCache.sub(intfs).computeIfAbsent(
! loader,
! (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
! );
! }
}
/*
* Check permissions required to create a Proxy class.
*
*** 389,555 ****
* will throw IllegalAccessError when the generated proxy class is
* being defined.
*/
private static void checkProxyAccess(Class<?> caller,
ClassLoader loader,
! List<Class<?>> interfaces)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = caller.getClassLoader();
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
! ReflectUtil.checkProxyPackageAccess(ccl, interfaces.toArray(EMPTY_CLASS_ARRAY));
! }
! }
!
! /*
! * a key used for proxy class with 0 implemented interfaces
! */
! private static final Object key0 = new Object();
!
! /*
! * Key1 and Key2 are optimized for the common use of dynamic proxies
! * that implement 1 or 2 interfaces.
! */
!
! /*
! * a key used for proxy class with 1 implemented interface
! */
! private static final class Key1 extends WeakReference<Class<?>> {
! private final int hash;
!
! Key1(Class<?> intf) {
! super(intf);
! this.hash = intf.hashCode();
! }
!
! @Override
! public int hashCode() {
! return hash;
! }
!
! @Override
! public boolean equals(Object obj) {
! Class<?> intf;
! return this == obj ||
! obj != null &&
! obj.getClass() == Key1.class &&
! (intf = get()) != null &&
! intf == ((Key1) obj).get();
! }
! }
!
! /*
! * a key used for proxy class with 2 implemented interfaces
! */
! private static final class Key2 extends WeakReference<Class<?>> {
! private final int hash;
! private final WeakReference<Class<?>> ref2;
!
! Key2(Class<?> intf1, Class<?> intf2) {
! super(intf1);
! hash = 31 * intf1.hashCode() + intf2.hashCode();
! ref2 = new WeakReference<>(intf2);
! }
!
! @Override
! public int hashCode() {
! return hash;
! }
!
! @Override
! public boolean equals(Object obj) {
! Class<?> intf1, intf2;
! return this == obj ||
! obj != null &&
! obj.getClass() == Key2.class &&
! (intf1 = get()) != null &&
! intf1 == ((Key2) obj).get() &&
! (intf2 = ref2.get()) != null &&
! intf2 == ((Key2) obj).ref2.get();
! }
! }
!
! /*
! * a key used for proxy class with any number of implemented interfaces
! * (used here for 3 or more only)
! */
! private static final class KeyX {
! private final int hash;
! private final WeakReference<Class<?>>[] refs;
!
! @SuppressWarnings("unchecked")
! KeyX(List<Class<?>> interfaces) {
! hash = Arrays.hashCode(interfaces.toArray());
! refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.size()];
! int i = 0;
! for (Class<?> intf : interfaces) {
! refs[i++] = new WeakReference<>(intf);
! }
! }
!
! @Override
! public int hashCode() {
! return hash;
! }
!
! @Override
! public boolean equals(Object obj) {
! return this == obj ||
! obj != null &&
! obj.getClass() == KeyX.class &&
! equals(refs, ((KeyX) obj).refs);
! }
!
! private static boolean equals(WeakReference<Class<?>>[] refs1,
! WeakReference<Class<?>>[] refs2) {
! if (refs1.length != refs2.length) {
! return false;
! }
! for (int i = 0; i < refs1.length; i++) {
! Class<?> intf = refs1[i].get();
! if (intf == null || intf != refs2[i].get()) {
! return false;
! }
! }
! return true;
! }
! }
!
! /**
! * A function that maps an array of interfaces to an optimal key where
! * Class objects representing interfaces are weakly referenced.
! */
! private static final class KeyFactory<T>
! implements BiFunction<T, List<Class<?>>, Object>
! {
! @Override
! public Object apply(T t, List<Class<?>> interfaces) {
! switch (interfaces.size()) {
! case 1: return new Key1(interfaces.get(0)); // the most frequent
! case 2: return new Key2(interfaces.get(0), interfaces.get(1));
! case 0: return key0;
! default: return new KeyX(interfaces);
! }
}
}
/**
! * A factory function that generates, defines and returns the proxy class
! * given the ClassLoader and array of interfaces.
*/
! private static final class ProxyClassFactory {
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
--- 420,461 ----
* will throw IllegalAccessError when the generated proxy class is
* being defined.
*/
private static void checkProxyAccess(Class<?> caller,
ClassLoader loader,
! Class<?> ... interfaces)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = caller.getClassLoader();
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
! ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
}
/**
! * Builder for a proxy class.
! *
! * If the module is not specified in this ProxyBuilder constructor,
! * it will map from the given loader and interfaces to the module
! * in which the proxy class will be defined.
*/
! private static final class ProxyBuilder {
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
+ // a reverse cache of defined proxy classes
+ private static final ClassLoaderValue<Boolean> reverseProxyCache =
+ new ClassLoaderValue<>();
+
private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
*** 599,610 ****
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
try {
! return UNSAFE.defineClass(proxyName, proxyClassFile, 0, proxyClassFile.length,
loader, null);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
--- 505,519 ----
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
try {
! Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
! 0, proxyClassFile.length,
loader, null);
+ reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
+ return pc;
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
*** 614,652 ****
throw new IllegalArgumentException(e.toString());
}
}
/**
! * Test if the given class is a proxy class
*/
static boolean isProxyClass(Class<?> c) {
! return proxyCache.containsValue(c);
! }
!
! /**
! * Returns the proxy class. It will return the cached proxy class
! * if exists; otherwise, it will create the proxy class and store in
! * the cache.
! */
! static Class<?> get(Module module, List<Class<?>> interfaces) {
! return proxyCache.get(module, interfaces);
}
- /**
- * a cache of proxy classes in the named and unnamed module
- */
- private static final WeakCache<Module, List<Class<?>>, Class<?>> proxyCache =
- new WeakCache<>(new KeyFactory<Module>(),
- new BiFunction<Module, List<Class<?>>, Class<?>>() {
- @Override
- public Class<?> apply(Module m, List<Class<?>> interfaces) {
- Objects.requireNonNull(m);
- return defineProxyClass(m, interfaces);
- }
- });
-
-
private static boolean isExportedType(Class<?> c) {
String pn = c.getPackageName();
return Modifier.isPublic(c.getModifiers()) && c.getModule().isExported(pn);
}
--- 523,540 ----
throw new IllegalArgumentException(e.toString());
}
}
/**
! * Test if given class is a class defined by
! * {@link #defineProxyClass(Module, List)}
*/
static boolean isProxyClass(Class<?> c) {
! return Boolean.TRUE.equals(
! reverseProxyCache.sub(c).get(c.getClassLoader()));
}
private static boolean isExportedType(Class<?> c) {
String pn = c.getPackageName();
return Modifier.isPublic(c.getModifiers()) && c.getModule().isExported(pn);
}
*** 683,711 ****
public String run() {
return System.getProperty("jdk.proxy.debug", "");
}
});
! private static final boolean isDebug() {
return !DEBUG.isEmpty();
}
! private static final boolean isDebug(String flag) {
return DEBUG.equals(flag);
}
- }
! /**
! * Builder for a proxy class.
! *
! * If the module is not specified in this ProxyBuilder constructor,
! * it will map from the given loader and interfaces to the module
! * in which the proxy class will be defined.
! */
! private static final class ProxyBuilder {
! final ClassLoader loader;
! final List<Class<?>> interfaces;
! final Module module;
ProxyBuilder(ClassLoader loader, List<Class<?>> interfaces) {
if (!VM.isModuleSystemInited()) {
throw new InternalError("Proxy is not supported until module system is fully initialzed");
}
if (interfaces.size() > 65535) {
--- 571,592 ----
public String run() {
return System.getProperty("jdk.proxy.debug", "");
}
});
! private static boolean isDebug() {
return !DEBUG.isEmpty();
}
! private static boolean isDebug(String flag) {
return DEBUG.equals(flag);
}
! // ProxyBuilder instance members start here....
!
! private final ClassLoader loader;
! private final List<Class<?>> interfaces;
! private final Module module;
ProxyBuilder(ClassLoader loader, List<Class<?>> interfaces) {
if (!VM.isModuleSystemInited()) {
throw new InternalError("Proxy is not supported until module system is fully initialzed");
}
if (interfaces.size() > 65535) {
*** 721,750 ****
this.interfaces = interfaces;
this.module = mapToModule(loader, interfaces, refTypes);
assert getLoader(module) == loader;
}
/**
! * Generate a proxy class. If the target module does not have any
* to any interface types, IllegalAccessError will be thrown by the VM
* at defineClass time.
*
* Must call the checkProxyAccess method to perform permission checks
* before calling this.
*/
! Class<?> build() {
! return ProxyClassFactory.get(module, interfaces);
}
/**
* Validate the given proxy interfaces and the given referenced types
* are visible to the defining loader.
*
* @throws IllegalArgumentException if it violates the restrictions specified
* in {@link Proxy#newProxyInstance}
*/
! static void validateProxyInterfaces(ClassLoader loader,
List<Class<?>> interfaces,
Set<Class<?>> refTypes)
{
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.size());
for (Class<?> intf : interfaces) {
--- 602,649 ----
this.interfaces = interfaces;
this.module = mapToModule(loader, interfaces, refTypes);
assert getLoader(module) == loader;
}
+ ProxyBuilder(ClassLoader loader, Class<?> intf) {
+ this(loader, Collections.singletonList(intf));
+ }
+
/**
! * Generate a proxy class and return its proxy Constructor with
! * accessible flag already set. If the target module does not have access
* to any interface types, IllegalAccessError will be thrown by the VM
* at defineClass time.
*
* Must call the checkProxyAccess method to perform permission checks
* before calling this.
*/
! Constructor<?> build() {
! Class<?> proxyClass = defineProxyClass(module, interfaces);
! final Constructor<?> cons;
! try {
! cons = proxyClass.getConstructor(constructorParams);
! } catch (NoSuchMethodException e) {
! throw new InternalError(e.toString(), e);
! }
! AccessController.doPrivileged(new PrivilegedAction<Void>() {
! public Void run() {
! cons.setAccessible(true);
! return null;
! }
! });
! return cons;
}
/**
* Validate the given proxy interfaces and the given referenced types
* are visible to the defining loader.
*
* @throws IllegalArgumentException if it violates the restrictions specified
* in {@link Proxy#newProxyInstance}
*/
! private static void validateProxyInterfaces(ClassLoader loader,
List<Class<?>> interfaces,
Set<Class<?>> refTypes)
{
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.size());
for (Class<?> intf : interfaces) {
*** 777,804 ****
/*
* Returns all types referenced by all public method signatures of
* the proxy interfaces
*/
! static Set<Class<?>> referencedTypes(ClassLoader loader, List<Class<?>> interfaces) {
return interfaces.stream()
.flatMap(intf -> Stream.of(intf.getMethods())
! .flatMap(m -> methodRefTypes(m))
.map(ProxyBuilder::getElementType)
.filter(t -> !t.isPrimitive()))
.collect(Collectors.toSet());
}
/*
* Extracts all types referenced on a method signature including
* its return type, parameter types, and exception types.
*/
! static Stream<Class<?>> methodRefTypes(Method m) {
return Stream.of(new Class<?>[] { m.getReturnType() },
m.getParameterTypes(),
m.getExceptionTypes())
! .flatMap(a -> Stream.of(a));
}
/**
* Returns the module that the generated proxy class belongs to.
*
--- 676,704 ----
/*
* Returns all types referenced by all public method signatures of
* the proxy interfaces
*/
! private static Set<Class<?>> referencedTypes(ClassLoader loader,
! List<Class<?>> interfaces) {
return interfaces.stream()
.flatMap(intf -> Stream.of(intf.getMethods())
! .flatMap(ProxyBuilder::methodRefTypes)
.map(ProxyBuilder::getElementType)
.filter(t -> !t.isPrimitive()))
.collect(Collectors.toSet());
}
/*
* Extracts all types referenced on a method signature including
* its return type, parameter types, and exception types.
*/
! private static Stream<Class<?>> methodRefTypes(Method m) {
return Stream.of(new Class<?>[] { m.getReturnType() },
m.getParameterTypes(),
m.getExceptionTypes())
! .flatMap(Stream::of);
}
/**
* Returns the module that the generated proxy class belongs to.
*
*** 811,821 ****
* If all proxy interfaces are public and at least one in a non-exported
* package, then the proxy class is in a dynamic module in a non-exported
* package. Reads edge and qualified exports are added for
* dynamic module to access.
*/
! static Module mapToModule(ClassLoader loader, List<Class<?>> interfaces, Set<Class<?>> refTypes) {
Map<Class<?>, Module> modulePrivateTypes = new HashMap<>();
Map<Class<?>, Module> packagePrivateTypes = new HashMap<>();
for (Class<?> intf : interfaces) {
Module m = intf.getModule();
if (Modifier.isPublic(intf.getModifiers())) {
--- 711,723 ----
* If all proxy interfaces are public and at least one in a non-exported
* package, then the proxy class is in a dynamic module in a non-exported
* package. Reads edge and qualified exports are added for
* dynamic module to access.
*/
! private static Module mapToModule(ClassLoader loader,
! List<Class<?>> interfaces,
! Set<Class<?>> refTypes) {
Map<Class<?>, Module> modulePrivateTypes = new HashMap<>();
Map<Class<?>, Module> packagePrivateTypes = new HashMap<>();
for (Class<?> intf : interfaces) {
Module m = intf.getModule();
if (Modifier.isPublic(intf.getModifiers())) {
*** 882,895 ****
// set up proxy class access to proxy interfaces and superinterfaces
Deque<Class<?>> deque = new LinkedList<>(interfaces);
Set<Class<?>> visited = new HashSet<>();
while (!deque.isEmpty()) {
Class<?> c = deque.poll();
! if (visited.contains(c)) {
continue;
}
- visited.add(c);
ensureAccess(target, c);
// add all superinterfaces
for (Class<?> intf : c.getInterfaces()) {
deque.add(intf);
--- 784,796 ----
// set up proxy class access to proxy interfaces and superinterfaces
Deque<Class<?>> deque = new LinkedList<>(interfaces);
Set<Class<?>> visited = new HashSet<>();
while (!deque.isEmpty()) {
Class<?> c = deque.poll();
! if (!visited.add(c)) {
continue;
}
ensureAccess(target, c);
// add all superinterfaces
for (Class<?> intf : c.getInterfaces()) {
deque.add(intf);
*** 904,914 ****
}
/*
* Ensure the given module can access the given class.
*/
! static void ensureAccess(Module target, Class<?> c) {
Module m = c.getModule();
// add read edge and qualified export for the target module to access
if (!target.canRead(m)) {
Modules.addReads(target, m);
}
--- 805,815 ----
}
/*
* Ensure the given module can access the given class.
*/
! private static void ensureAccess(Module target, Class<?> c) {
Module m = c.getModule();
// add read edge and qualified export for the target module to access
if (!target.canRead(m)) {
Modules.addReads(target, m);
}
*** 919,929 ****
}
/*
* Ensure the given class is visible to the class loader.
*/
! static void ensureVisible(ClassLoader ld, Class<?> c) {
Class<?> type = null;
try {
type = Class.forName(c.getName(), false, ld);
} catch (ClassNotFoundException e) {
}
--- 820,830 ----
}
/*
* Ensure the given class is visible to the class loader.
*/
! private static void ensureVisible(ClassLoader ld, Class<?> c) {
Class<?> type = null;
try {
type = Class.forName(c.getName(), false, ld);
} catch (ClassNotFoundException e) {
}
*** 931,963 ****
throw new IllegalArgumentException(c.getName() +
" referenced from a method is not visible from class loader");
}
}
! static Class<?> getElementType(Class<?> type) {
Class<?> e = type;
while (e.isArray()) {
e = e.getComponentType();
}
return e;
}
! private static final WeakHashMap<ClassLoader, Module> dynProxyModules = new WeakHashMap<>();
private static final AtomicInteger counter = new AtomicInteger();
/*
* Define a dynamic module for the generated proxy classes in a non-exported package
* named com.sun.proxy.$MODULE.
*
* Each class loader will have one dynamic module.
*/
! static Module getDynamicModule(ClassLoader loader) {
! return dynProxyModules.computeIfAbsent(loader, ld -> {
// create a dynamic module and setup module access
String mn = "jdk.proxy" + counter.incrementAndGet();
String pn = PROXY_PACKAGE_PREFIX + "." + mn;
! Module m = Modules.defineModule(loader, mn, Collections.singleton(pn));
Modules.addReads(m, Proxy.class.getModule());
// java.base to create proxy instance
Modules.addExports(m, pn, Object.class.getModule());
return m;
});
--- 832,865 ----
throw new IllegalArgumentException(c.getName() +
" referenced from a method is not visible from class loader");
}
}
! private static Class<?> getElementType(Class<?> type) {
Class<?> e = type;
while (e.isArray()) {
e = e.getComponentType();
}
return e;
}
! private static final ClassLoaderValue<Module> dynProxyModules =
! new ClassLoaderValue<>();
private static final AtomicInteger counter = new AtomicInteger();
/*
* Define a dynamic module for the generated proxy classes in a non-exported package
* named com.sun.proxy.$MODULE.
*
* Each class loader will have one dynamic module.
*/
! private static Module getDynamicModule(ClassLoader loader) {
! return dynProxyModules.computeIfAbsent(loader, (ld, clv) -> {
// create a dynamic module and setup module access
String mn = "jdk.proxy" + counter.incrementAndGet();
String pn = PROXY_PACKAGE_PREFIX + "." + mn;
! Module m = Modules.defineModule(ld, mn, Collections.singleton(pn));
Modules.addReads(m, Proxy.class.getModule());
// java.base to create proxy instance
Modules.addExports(m, pn, Object.class.getModule());
return m;
});
*** 1060,1103 ****
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
Objects.requireNonNull(h);
! final List<Class<?>> intfs = List.of(interfaces); // interfaces cloned
! final SecurityManager sm = System.getSecurityManager();
! final Class<?> caller = Reflection.getCallerClass();
! if (sm != null) {
! checkProxyAccess(caller, loader, intfs);
! }
/*
! * Look up or generate the designated proxy class.
*/
! Class<?> cl = new ProxyBuilder(loader, intfs).build();
! return newProxyInstance(cl, caller, h);
}
! private static Object newProxyInstance(Class<?> proxyClass, Class<?> caller, InvocationHandler h) {
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
! final SecurityManager sm = System.getSecurityManager();
! if (sm != null) {
! checkNewProxyPermission(caller, proxyClass);
}
- final Constructor<?> cons = proxyClass.getConstructor(constructorParams);
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- cons.setAccessible(true);
- return null;
- }
- });
return cons.newInstance(new Object[]{h});
! } catch (IllegalAccessException | InstantiationException | NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
--- 962,996 ----
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
Objects.requireNonNull(h);
! final Class<?> caller = System.getSecurityManager() == null
! ? null
! : Reflection.getCallerClass();
/*
! * Look up or generate the designated proxy class and its constructor.
*/
! Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);
! return newProxyInstance(caller, cons, h);
}
! private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager
! Constructor<?> cons,
! InvocationHandler h) {
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
! if (caller != null) {
! checkNewProxyPermission(caller, cons.getDeclaringClass());
}
return cons.newInstance(new Object[]{h});
! } catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
*** 1148,1158 ****
* @return {@code true} if the class is a proxy class and
* {@code false} otherwise
* @throws NullPointerException if {@code cl} is {@code null}
*/
public static boolean isProxyClass(Class<?> cl) {
! return Proxy.class.isAssignableFrom(cl) && ProxyClassFactory.isProxyClass(cl);
}
/**
* Returns the invocation handler for the specified proxy instance.
*
--- 1041,1051 ----
* @return {@code true} if the class is a proxy class and
* {@code false} otherwise
* @throws NullPointerException if {@code cl} is {@code null}
*/
public static boolean isProxyClass(Class<?> cl) {
! return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
}
/**
* Returns the invocation handler for the specified proxy instance.
*
< prev index next >