This is an automated email from the ASF dual-hosted git repository.

struberg 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 82e65b4  OWB-1375 simplify defineClass handling
82e65b4 is described below

commit 82e65b4a55e18ed3c67f435cd4ef05cac0c4ab34
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Mon Mar 15 20:33:02 2021 +0100

    OWB-1375 simplify defineClass handling
---
 .../java/org/apache/webbeans/proxy/Unsafe.java     | 70 +++++++++-------------
 1 file changed, 28 insertions(+), 42 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 d85dbd5..7ba6d20 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
@@ -26,8 +26,6 @@ import java.lang.reflect.Method;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
@@ -50,8 +48,8 @@ public class Unsafe
     private final AtomicReference<Method> unsafeDefineClass = new 
AtomicReference<>();
 
     // defineClass method on ClassLoader
-    private Boolean useDefineClassMethod = null;
-    private final Map<ClassLoader, Method> defineClassMethodsByClassLoader = 
new HashMap<>();
+    private volatile boolean useDefineClassMethod = true;
+    private volatile Method defineClassMethod = null;
 
     // java 16
     private volatile Method privateLookup;
@@ -148,54 +146,42 @@ public class Unsafe
                                            Class<?> parent)
             throws ProxyGenerationException
     {
-        Method defineClassMethod = null;
 
-        if (useDefineClassMethod == null || 
Boolean.TRUE.equals(useDefineClassMethod))
+        if (defineClassMethod == null && useDefineClassMethod)
         {
-            defineClassMethod = 
defineClassMethodsByClassLoader.get(classLoader);
-
-            if (defineClassMethod == null)
+            Method defineClassMethodTmp = null;
+            try
             {
-                Class<?> clClazz = classLoader.getClass();
-
-                do
-                {
-                    try
-                    {
-                        defineClassMethod = 
clClazz.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, 
int.class);
-                    }
-                    catch (NoSuchMethodException e)
-                    {
-                        // do nothing, we need to search the superclass
-                    }
+                // 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);
+            }
+            catch (NoSuchMethodException e)
+            {
+                // all fine, we just skip over from here
+            }
 
-                    clClazz = clClazz.getSuperclass();
-                } while (defineClassMethod == null && clClazz != Object.class);
 
-                if (defineClassMethod == null)
-                {
-                    // This ClassLoader does not have any accessible 
defineClass method
-                    useDefineClassMethod = Boolean.FALSE;
-                }
-                else if (!defineClassMethod.isAccessible())
+            if (defineClassMethodTmp == null)
+            {
+                // This ClassLoader does not have any accessible defineClass 
method
+                useDefineClassMethod = false;
+            }
+            else if (!defineClassMethodTmp.isAccessible())
+            {
+                try
                 {
-                    try
-                    {
-                        defineClassMethod.setAccessible(true);
-                        defineClassMethodsByClassLoader.put(classLoader, 
defineClassMethod);
-                    }
-                    catch (RuntimeException re)
-                    {
-                        // likely j9 or not accessible via security, let's use 
unsafe
-                        defineClassMethod = null;
-                        useDefineClassMethod = Boolean.FALSE;
-                    }
+                    defineClassMethodTmp.setAccessible(true);
                 }
-                else
+                catch (RuntimeException re)
                 {
-                    defineClassMethodsByClassLoader.put(classLoader, 
defineClassMethod);
+                    // likely j9 or not accessible via security, let's use 
unsafe or MethodHandle as fallbacks
+                    defineClassMethodTmp = null;
+                    useDefineClassMethod = false;
                 }
             }
+
+            defineClassMethod = defineClassMethodTmp;
         }
 
         try

Reply via email to