This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 26aaec0 OWB-1306 better support of java versions for our unsafe usage
26aaec0 is described below
commit 26aaec0274c994336f9bca30b4609065ec323864
Author: Romain Manni-Bucau <[email protected]>
AuthorDate: Thu Dec 12 07:43:52 2019 +0100
OWB-1306 better support of java versions for our unsafe usage
---
.../java/org/apache/webbeans/proxy/Unsafe.java | 53 ++++++++++++++++++++--
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
b/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
index 09f9fce..8df2a12 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/proxy/Unsafe.java
@@ -18,6 +18,7 @@
*/
package org.apache.webbeans.proxy;
+import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -37,6 +38,7 @@ public class Unsafe
* initializing the class.
*/
private Object unsafe;
+ private Object internalUnsafe;
private Method unsafeAllocateInstance;
private final AtomicReference<Method> unsafeDefineClass = new
AtomicReference<>();
@@ -58,13 +60,25 @@ public class Unsafe
return null;
}
});
+ this.internalUnsafe =
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+ try // j11, unwrap unsafe, it owns defineClass now and no more
theUnsafe
+ {
+ final Field theInternalUnsafe =
unsafeClass.getDeclaredField("theInternalUnsafe");
+ theInternalUnsafe.setAccessible(true);
+ return theInternalUnsafe.get(null).getClass();
+ }
+ catch (final Exception notJ11OrMore)
+ {
+ return unsafe;
+ }
+ });
if (unsafe != null)
{
unsafeAllocateInstance =
AccessController.doPrivileged((PrivilegedAction<Method>) () -> {
try
{
- Method mtd =
unsafeClass.getDeclaredMethod("allocateInstance", Class.class);
+ Method mtd =
unsafe.getClass().getDeclaredMethod("allocateInstance", Class.class);
mtd.setAccessible(true);
return mtd;
}
@@ -73,6 +87,37 @@ public class Unsafe
return null; // use newInstance()
}
});
+
+ try
+ {
+ final Class<?> rootLoaderClass =
Class.forName("java.lang.ClassLoader");
+ rootLoaderClass.getDeclaredMethod(
+ "defineClass", new Class[] { String.class, byte[].class,
int.class, int.class })
+ .setAccessible(true);
+ rootLoaderClass.getDeclaredMethod(
+ "defineClass", new Class[] {
+ String.class, byte[].class, int.class, int.class,
ProtectionDomain.class })
+ .setAccessible(true);
+ }
+ catch (final Exception e)
+ {
+ try // some j>8, since we have unsafe let's use it
+ {
+ final Class<?> rootLoaderClass =
Class.forName("java.lang.ClassLoader");
+ final sun.misc.Unsafe un =
sun.misc.Unsafe.class.cast(unsafe);
+ final long accOffset =
un.objectFieldOffset(AccessibleObject.class.getDeclaredField("override"));
+
+
un.putBoolean(rootLoaderClass.getDeclaredMethod("defineClass",
+ new Class[]{String.class, byte[].class, int.class,
int.class}), accOffset, true);
+
un.putBoolean(rootLoaderClass.getDeclaredMethod("defineClass",
+ new Class[]{String.class, byte[].class, int.class,
int.class, ProtectionDomain.class}),
+ accOffset, true);
+ }
+ catch (final Exception ex)
+ {
+ // no-op
+ }
+ }
}
}
@@ -156,7 +201,7 @@ public class Unsafe
{
synchronized (this)
{
- final Class<?> unsafeClass = getUnsafeClass();
+ final Class<?> unsafeClass = internalUnsafe.getClass();
value =
AccessController.doPrivileged((PrivilegedAction<Method>) () -> {
try
{
@@ -208,10 +253,9 @@ public class Unsafe
private Class<?> getUnsafeClass()
{
- Class<?> unsafeClass;
try
{
- unsafeClass =
AccessController.doPrivileged((PrivilegedAction<Class<?>>) () -> {
+ return AccessController.doPrivileged((PrivilegedAction<Class<?>>)
() -> {
try
{
return
Thread.currentThread().getContextClassLoader().loadClass("sun.misc.Unsafe");
@@ -233,6 +277,5 @@ public class Unsafe
{
throw new IllegalStateException("Cannot get sun.misc.Unsafe
class", e);
}
- return unsafeClass;
}
}