Only prefer JDK 9+ Lookup.defineClass API if ClassLoader matches
Closes gh-22416
This commit is contained in:
parent
7a7c7f51e3
commit
5d8a34fee6
|
|
@ -491,7 +491,10 @@ public class ReflectUtils {
|
||||||
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {
|
ProtectionDomain protectionDomain, Class<?> contextClass) throws Exception {
|
||||||
|
|
||||||
Class c = null;
|
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 {
|
try {
|
||||||
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
|
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
|
||||||
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
|
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
|
||||||
|
|
@ -510,29 +513,52 @@ public class ReflectUtils {
|
||||||
throw new CodeGenerationException(ex);
|
throw new CodeGenerationException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (protectionDomain == null) {
|
|
||||||
protectionDomain = PROTECTION_DOMAIN;
|
// Classic option: protected ClassLoader.defineClass method
|
||||||
}
|
if (c == null && classLoaderDefineClassMethod != null) {
|
||||||
if (c == null) {
|
if (protectionDomain == null) {
|
||||||
if (classLoaderDefineClassMethod != null) {
|
protectionDomain = PROTECTION_DOMAIN;
|
||||||
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
|
}
|
||||||
try {
|
Object[] args = new Object[]{className, b, 0, b.length, protectionDomain};
|
||||||
if (!classLoaderDefineClassMethod.isAccessible()) {
|
try {
|
||||||
classLoaderDefineClassMethod.setAccessible(true);
|
if (!classLoaderDefineClassMethod.isAccessible()) {
|
||||||
}
|
classLoaderDefineClassMethod.setAccessible(true);
|
||||||
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
|
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException ex) {
|
c = (Class) classLoaderDefineClassMethod.invoke(loader, args);
|
||||||
throw new CodeGenerationException(ex.getTargetException());
|
}
|
||||||
}
|
catch (InvocationTargetException ex) {
|
||||||
catch (Throwable ex) {
|
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);
|
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.
|
// Force static initializers to run.
|
||||||
Class.forName(className, true, loader);
|
Class.forName(className, true, loader);
|
||||||
return c;
|
return c;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue