From 3e8556316990229f141e628eaaf742a8a10bce74 Mon Sep 17 00:00:00 2001 From: Ondro Mihalyi Date: Mon, 2 Sep 2024 23:57:31 +0200 Subject: [PATCH] JPMS improvements: Experiments with GF Embedded Discovered a flaw in the solution for ProxyServiceImpl --- .../com/sun/ejb/codegen/ClassGenerator.java | 25 +------------------ .../weld/services/ProxyServicesImpl.java | 8 ++++-- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/ClassGenerator.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/ClassGenerator.java index 6b729bd898e..2749b79faf6 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/ClassGenerator.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/codegen/ClassGenerator.java @@ -44,29 +44,6 @@ public final class ClassGenerator { private static final Logger LOG = Logger.getLogger(ClassGenerator.class.getName()); -// private static Method defineClassMethod; -// private static Method defineClassMethodSM; -// -// static { -// try { -// final PrivilegedExceptionAction action = () -> { -// final Class cl = Class.forName("java.lang.ClassLoader"); -// final String name = "defineClass"; -// defineClassMethod = cl.getDeclaredMethod(name, String.class, byte[].class, int.class, int.class); -// ClassLoaderMethods.defineClassMethod.setAccessible(true); -// defineClassMethodSM = cl.getDeclaredMethod( -// name, String.class, byte[].class, int.class, int.class, ProtectionDomain.class); -// ClassLoaderMethods.defineClassMethodSM.setAccessible(true); -// return null; -// }; -// AccessController.doPrivileged(action); -// LOG.config("ClassLoader methods capable of generating classes were successfully detected."); -// } catch (final Exception e) { -// throw new Error("Could not initialize access to ClassLoader.defineClass method.", e); -// } -// } - - private ClassGenerator() { // hidden } @@ -256,7 +233,7 @@ private static boolean useMethodHandles(final ClassLoader loader, final Class } // The bootstrap CL used by embedded glassfish doesn't remember generated classes // Further ClassLoader.findClass calls will fail. - if (anchorClass == null || loader.getParent() == null || loader.getClass() == ASURLClassLoader.class) { + if (anchorClass == null || loader.getClass() == ASURLClassLoader.class) { return false; } // Use MethodHandles.Lookup only if the anchor run-time Package defined by CL. diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ProxyServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ProxyServicesImpl.java index 7797387ee6c..bf172a98295 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ProxyServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/ProxyServicesImpl.java @@ -50,7 +50,8 @@ public class ProxyServicesImpl implements ProxyServices { private final ClassLoaderHierarchy classLoaderHierarchy; - private Map classPoolMap = Collections.synchronizedMap(new WeakHashMap<>()); + // probably shouldn't be static but moved to a singleton service + private static Map classPoolMap = Collections.synchronizedMap(new WeakHashMap<>()); /** * @param services immediately used to find a {@link ClassLoaderHierarchy} service @@ -59,13 +60,16 @@ public ProxyServicesImpl(final ServiceLocator services) { classLoaderHierarchy = services.getService(ClassLoaderHierarchy.class); } + /* This solution is not ideal - it creates the new class in the CL of the originalClass + (most often server CL or bootstrap CL), while the previous solution created it in the app classloader. + */ @Override public Class defineClass(final Class originalClass, final String className, final byte[] classBytes, final int off, final int len) throws ClassFormatError { try { final String originalPackageName = originalClass.getPackageName(); String modifiedClassName = originalClass.getName() + "_GlassFishWeldProxy"; - final ClassLoader originalClassCL = getClassLoaderforBean(originalClass); + final ClassLoader originalClassCL = originalClass.getClassLoader(); final ClassPool classPool = classPoolMap.computeIfAbsent(originalClassCL, cl -> new ClassPool()); while (classPool.getOrNull(modifiedClassName) != null) { modifiedClassName += "_";