Only prefer JDK 9+ Lookup.defineClass API if ClassLoader matches

Closes gh-22416
master
Juergen Hoeller 6 years ago
parent 7a7c7f51e3
commit 5d8a34fee6
  1. 36
      spring-core/src/main/java/org/springframework/cglib/core/ReflectUtils.java

@ -491,7 +491,10 @@ public class ReflectUtils {
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {
Class c = null;
if (contextClass != null && privateLookupInMethod != null && lookupDefineClassMethod != null) {
// Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matches
if (contextClass != null && contextClass.getClassLoader() == loader &&
privateLookupInMethod != null && lookupDefineClassMethod != null) {
try {
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
@ -510,11 +513,12 @@ public class ReflectUtils {
throw new CodeGenerationException(ex);
}
}
// Classic option: protected ClassLoader.defineClass method
if (c == null && classLoaderDefineClassMethod != null) {
if (protectionDomain == null) {
protectionDomain = PROTECTION_DOMAIN;
}
if (c == null) {
if (classLoaderDefineClassMethod != null) {
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
try {
if (!classLoaderDefineClassMethod.isAccessible()) {
@ -526,13 +530,35 @@ public class ReflectUtils {
throw new CodeGenerationException(ex.getTargetException());
}
catch (Throwable ex) {
// Fall through if setAccessible fails with InaccessibleObjectException on JDK 9+
// (on the module path and/or with a JVM bootstrapped with --illegal-access=deny)
if (!ex.getClass().getName().endsWith("InaccessibleObjectException")) {
throw new CodeGenerationException(ex);
}
}
else {
throw new CodeGenerationException(THROWABLE);
}
// Fallback option: JDK 9+ Lookup.defineClass API even if ClassLoader does not match
if (c == null && contextClass != null && contextClass.getClassLoader() != loader &&
privateLookupInMethod != null && lookupDefineClassMethod != null) {
try {
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
c = (Class) lookupDefineClassMethod.invoke(lookup, b);
}
catch (InvocationTargetException ex) {
throw new CodeGenerationException(ex.getTargetException());
}
catch (Throwable ex) {
throw new CodeGenerationException(ex);
}
}
// No defineClass variant available at all?
if (c == null) {
throw new CodeGenerationException(THROWABLE);
}
// Force static initializers to run.
Class.forName(className, true, loader);
return c;

Loading…
Cancel
Save