Author: rmannibucau
Date: Wed May 3 12:12:22 2017
New Revision: 1793640
URL: http://svn.apache.org/viewvc?rev=1793640&view=rev
Log:
OWB-1181 use unsafe to define classes when classloader flavor is not accessible
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java?rev=1793640&r1=1793639&r2=1793640&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/AbstractProxyFactory.java
Wed May 3 12:12:22 2017
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Logger;
@@ -65,6 +66,7 @@ public abstract class AbstractProxyFacto
*/
private Object unsafe = null;
private Method unsafeAllocateInstance = null;
+ private Method unsafeDefineClass;
private final int javaVersion;
@@ -343,15 +345,30 @@ public abstract class AbstractProxyFacto
clazz = clazz.getSuperclass();
} while (defineClassMethod == null && clazz != Object.class);
- if (defineClassMethod == null)
+ if (defineClassMethod != null && !defineClassMethod.isAccessible())
{
- throw new ProxyGenerationException("could not find 'defineClass'
method in the ClassLoader!");
+ try
+ {
+ defineClassMethod.setAccessible(true);
+ }
+ catch (RuntimeException re) // likely j9, let's use unsafe
+ {
+ defineClassMethod = null;
+ }
}
- defineClassMethod.setAccessible(true);
try
{
- Class<T> definedClass = (Class<T>)
defineClassMethod.invoke(classLoader, proxyName, proxyBytes, 0,
proxyBytes.length);
+ final Class<T> definedClass;
+
+ if (defineClassMethod != null)
+ {
+ definedClass = (Class<T>)
defineClassMethod.invoke(classLoader, proxyName, proxyBytes, 0,
proxyBytes.length);
+ }
+ else
+ {
+ definedClass = (Class<T>) unsafeDefineClass.invoke(unsafe,
proxyName, proxyBytes, 0, proxyBytes.length, classLoader, null);
+ }
return (Class<T>) Class.forName(definedClass.getName(), true,
classLoader);
}
@@ -744,6 +761,22 @@ public abstract class AbstractProxyFacto
}
}
});
+ unsafeDefineClass = AccessController.doPrivileged(new
PrivilegedAction<Method>()
+ {
+ @Override
+ public Method run()
+ {
+ try
+ {
+ return unsafeClass.getDeclaredMethod("defineClass",
+ String.class, byte[].class, int.class,
int.class, ClassLoader.class, ProtectionDomain.class);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("Cannot get
Unsafe.defineClass", e);
+ }
+ }
+ });
}
}