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