diff --git a/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java b/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java index 5d430de779..43fa543872 100644 --- a/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java +++ b/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java @@ -403,6 +403,10 @@ public Class getProxyClass() { proxyClassName = proxyClassName.replaceFirst(JAVA, WELD_PROXY_PREFIX); } else if (proxyClassName.startsWith(JAKARTA)) { proxyClassName = proxyClassName.replaceFirst(JAKARTA, WELD_PROXY_PREFIX); + } else if (bean != null && shouldRelocateProxy(bean.getBeanClass())) { + // Target lives in a named module that doesn't open its package to Weld. + // Define the proxy into Weld's own package to avoid the opens requirement to the named module. + proxyClassName = WELD_PROXY_PREFIX + "." + proxyClassName; } Class proxyClass = null; Class originalClass = bean != null ? bean.getBeanClass() : proxiedBeanType; @@ -982,6 +986,21 @@ protected Class toClass(ClassFile ct, Class originalClass, ProxyServices p } } + private static boolean shouldRelocateProxy(Class originalType) { + final Module module = originalType.getModule(); + if (module == null || !module.isNamed()) { + return false; // classpath / unnamed module: MethodHandles.privateLookupIn works fine + } + // Only relocate proxy when we have a public modifier as we cannot override package-private methods. + // package-private access is intentionally handled by defineWithMethodLookup + if (!Modifier.isPublic(originalType.getModifiers())) { + return false; + } + final String pkg = originalType.getPackageName(); + // We only need to relocate if the module is not already open to this module + return !module.isOpen(pkg, ProxyFactory.class.getModule()); + } + /** * When creating a proxy class name we can sometimes determine it's package as well. */