in webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java [175:313]
public <T> Class<T> defineAndLoadClass(ClassLoader classLoader, String proxyName, byte[] proxyBytes,
Class<?> parent)
throws ProxyGenerationException
{
Class<?> definedClass = null;
try
{
// CHECKSTYLE:OFF
switch (defineClassImpl) {
case 0: // unset
case 1: // classloader
{
if (defineClassMethod == null)
{
Method defineClassMethodTmp;
try
{
// defineClass is a final method on the abstract base ClassLoader
// thus we need to cache it only once
defineClassMethodTmp = ClassLoader.class.getDeclaredMethod(
"defineClass", String.class, byte[].class, int.class, int.class);
if (!defineClassMethodTmp.isAccessible())
{
try
{
defineClassMethodTmp.setAccessible(true);
defineClassMethod = defineClassMethodTmp;
}
catch (final RuntimeException re)
{
// likely j9 or not accessible via security, let's use unsafe or MethodHandle as fallbacks
}
}
}
catch (final NoSuchMethodException e)
{
// all fine, we just skip over from here
}
}
if (defineClassMethod != null)
{
try
{
definedClass = Class.class.cast(defineClassMethod.invoke(
classLoader, proxyName, proxyBytes, 0, proxyBytes.length));
defineClassImpl = 1;
break;
}
catch (final Throwable t)
{
definedClass = handleLinkageError(t, proxyName, classLoader);
if (definedClass != null)
{
defineClassImpl = 1;
break;
}
}
}
}
case 2: // lookup
{
if (privateLookup == null)
{
synchronized (this)
{
if (privateLookup == null)
{
try
{
lookup = MethodHandles.lookup();
defineClass = lookup.getClass().getMethod("defineClass", byte[].class);
privateLookup = MethodHandles.class.getDeclaredMethod(
"privateLookupIn", Class.class, MethodHandles.Lookup.class);
}
catch (final Exception re)
{
// no-op
}
}
}
}
if (privateLookup != null)
{
try
{
final MethodHandles.Lookup lookupInstance = MethodHandles.Lookup.class.cast(
privateLookup.invoke(
null,
proxyName.startsWith("org.apache.webbeans.custom.signed.") ?
CustomSignedProxyPackageMarker.class :
proxyName.startsWith("org.apache.webbeans.custom.") ?
CustomProxyPackageMarker.class : parent,
lookup));
definedClass = (Class<T>) defineClass.invoke(lookupInstance, proxyBytes);
defineClassImpl = 2;
break;
}
catch (final Exception e)
{
definedClass = handleLinkageError(e, proxyName, classLoader);
if (definedClass != null)
{
defineClassImpl = 2;
break;
}
}
}
}
case 3: // unlikely - unsafe
try
{
definedClass = Class.class.cast(unsafeDefineClass().invoke(
internalUnsafe, proxyName, proxyBytes, 0, proxyBytes.length, classLoader, null));
defineClassImpl = 3;
}
catch (final Throwable t)
{
definedClass = handleLinkageError(t, proxyName, classLoader);
}
break;
default:
throw new IllegalAccessError("Unknown defineClass impl: " + defineClassImpl);
}
// CHECKSTYLE:ON
if (definedClass == null)
{
throw new IllegalStateException("Can't define proxy " + proxyName);
}
return (Class<T>) Class.forName(definedClass.getName(), true, classLoader);
}
catch (final Throwable e)
{
return onProxyGenerationError(e, proxyName, classLoader);
}
}