openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject [openwebbeans] branch master updated: OWB-1306 better support of java versions for our unsafe usage
Date Thu, 12 Dec 2019 06:44:08 GMT
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 <rmannibucau@apache.org>
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;
     }
 }


Mime
View raw message