|
|
|
@ -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; |
|
|
|
|