From 4f4383cbbb7d8cd70c9e5166cd17309e70f68fc2 Mon Sep 17 00:00:00 2001 From: lprimak Date: Fri, 7 Mar 2025 00:57:29 -0600 Subject: [PATCH 01/32] bugfix: EAR deployment bugs found - fixed current deployment context - made it a regular thread local, not queue - only add CDI bundles that are not UNKNOWN - disable injection on EAR-root context (wrong context mode) - actually destroy deployment ClassLoader shareableTemp correctly - added fish.payara.ear-combined-cdi-deployment property to force combined EAR CDI deployment - Jax-JS Json-B injection retrives the correct BeanManager based on the actual type of the injection point desired --- appserver/web/weld-integration/pom.xml | 5 ++ .../org/glassfish/weld/DeploymentImpl.java | 6 +- .../glassfish/weld/GlassFishWeldProvider.java | 12 ++- .../weld/JaxRSJsonContextResolver.java | 85 +++++++++++++++++++ .../java/org/glassfish/weld/WeldDeployer.java | 26 ++++-- .../weld/services/InjectionServicesImpl.java | 7 +- ...jersey.internal.spi.ForcedAutoDiscoverable | 1 + .../v3/server/ApplicationLifecycle.java | 18 ++-- .../common/DeploymentContextImpl.java | 2 +- 9 files changed, 134 insertions(+), 28 deletions(-) create mode 100644 appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java create mode 100644 appserver/web/weld-integration/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable diff --git a/appserver/web/weld-integration/pom.xml b/appserver/web/weld-integration/pom.xml index 2ba5fe14572..9e4f67672c4 100644 --- a/appserver/web/weld-integration/pom.xml +++ b/appserver/web/weld-integration/pom.xml @@ -83,6 +83,7 @@ **/faces-config.xml **/com.sun.faces.spi.FacesConfigResourceProvider **/jakarta.enterprise.inject.spi.Extension + **/org.glassfish.jersey.internal.spi.* @@ -200,6 +201,10 @@ fish.payara.server.internal.transaction jta ${project.version} + + + jakarta.json.bind + jakarta.json.bind-api jakarta.xml.ws diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java index 620314edebf..7c14b890c05 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java @@ -159,6 +159,7 @@ public DeploymentImpl(ReadableArchive archive, this.archiveFactory = archiveFactory; this.context = context; this.injectionManager = injectionManager; + this.contextId = moduleName != null? moduleName : archive.getName(); // Collect /lib Jar BDAs (if any) from the parent module. // If we've produced BDA(s) from any /lib jars, return as @@ -177,7 +178,6 @@ public DeploymentImpl(ReadableArchive archive, this.appName = "CDIApp"; } - this.contextId = moduleName != null? moduleName : archive.getName(); createModuleBda(archive, ejbs, context, contextId); } @@ -274,7 +274,9 @@ private Set filterBDAs(Set bdas, List } private void addBeanDeploymentArchives(RootBeanDeploymentArchive bda) { - rootBDAs(bda).add(bda); + if (bda.getModuleBDAType() != BDAType.UNKNOWN) { + rootBDAs(bda).add(bda); + } } private Set rootBDAs(RootBeanDeploymentArchive bda) { diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java index 94ffbb866da..c0c266e5871 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2024] [Payara Foundation and/or its affiliates] +// Portions Copyright [2024-2025] [Payara Foundation and/or its affiliates] package org.glassfish.weld; @@ -55,6 +55,7 @@ import jakarta.enterprise.inject.spi.CDIProvider; import java.util.Map; import java.util.Set; +import static org.glassfish.weld.JaxRSJsonContextResolver.currentType; /** * @author JJ Snyder @@ -103,6 +104,15 @@ protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { return super.unsatisfiedBeanManager(callerClassName); } + + @Override + protected String getCallingClassName() { + if (currentType.get() != null) { + return currentType.get().getName(); + } else { + return super.getCallingClassName(); + } + } } @Override diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java new file mode 100644 index 00000000000..eee35965191 --- /dev/null +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -0,0 +1,85 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2025] Payara Foundation and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://github.com/payara/Payara/blob/main/LICENSE.txt + * See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * The Payara Foundation designates this particular file as subject to the "Classpath" + * exception as provided by the Payara Foundation in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ +package org.glassfish.weld; + +import jakarta.annotation.Priority; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.ws.rs.ConstrainedTo; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.FeatureContext; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.ext.ContextResolver; +import org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import static jakarta.ws.rs.RuntimeType.SERVER; +import static org.glassfish.jersey.internal.spi.AutoDiscoverable.DEFAULT_PRIORITY; + +/** + * Works in conjunction with {@link org.glassfish.weld.GlassFishWeldProvider} to provide the + * correct {@link Jsonb} instance based on the type of Jax-RS resource class being processed. + * + * This includes creating {@link Jsonb} instances that contains correct {@link jakarta.enterprise.inject.spi.BeanManager} + */ +@ConstrainedTo(SERVER) +@Priority(DEFAULT_PRIORITY) +@Produces(MediaType.APPLICATION_JSON) +public class JaxRSJsonContextResolver implements ContextResolver, ForcedAutoDiscoverable { + private final Map, Jsonb> jsonbMap = new ConcurrentHashMap<>(); + static final ThreadLocal> currentType = new ThreadLocal<>(); + + @Override + public void configure(FeatureContext context) { + context.register(JaxRSJsonContextResolver.class); + } + + @Override + public Jsonb getContext(Class type) { + return jsonbMap.computeIfAbsent(type, var -> { + currentType.set(type); + try { + return JsonbBuilder.create(); + } finally { + currentType.remove(); + } + }); + } +} diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java index d049c743e07..2bae45ddd6a 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java @@ -191,6 +191,8 @@ public class WeldDeployer extends SimpleDeployer()); @@ -528,9 +536,10 @@ private void processApplicationLoaded(ApplicationInfo applicationInfo) { } else if (!deploymentImpl.getRootBDAs().isEmpty()) { completeDeployment(deploymentImpl); // Legacy EJB-Jar scenario, one Weld instance per EAR - RootBeanDeploymentArchive bda = deploymentImpl.getRootBDAs().iterator().next(); - WeldBootstrap bootstrap = unifyBootstrap(bda, applicationInfo); - startWeldBootstrap(applicationInfo, bda, bootstrap, deploymentImpl, componentInvocation); + RootBeanDeploymentArchive firstBDA = deploymentImpl.getRootBDAs().stream().findFirst().get(); + WeldBootstrap bootstrap = ensureWeldBootstrapCreated(firstBDA.context, applicationInfo); + deploymentImpl.getRootBDAs().forEach(bda -> unifyBootstrap(bda, bootstrap)); + startWeldBootstrap(applicationInfo, firstBDA, bootstrap, deploymentImpl, componentInvocation); } } catch (Throwable t) { doBootstrapShutdown(applicationInfo); @@ -563,11 +572,10 @@ private void completeDeployment(DeploymentImpl deploymentImpl) { addCdiServicesToNonModuleBdas(deploymentImpl.getRarRootBdas(), services.getService(InjectionManager.class)); } - private WeldBootstrap unifyBootstrap(BeanDeploymentArchiveImpl rootArchive, ApplicationInfo applicationInfo) { - WeldBootstrap bootstrap = ensureWeldBootstrapCreated(rootArchive.context, applicationInfo); + private void unifyBootstrap(BeanDeploymentArchiveImpl rootArchive, WeldBootstrap bootstrap) { + rootArchive.weldBootstrap = bootstrap; rootArchive.getBeanDeploymentArchives().stream().map(BeanDeploymentArchiveImpl.class::cast) .forEach(bda -> bda.weldBootstrap = bootstrap); - return bootstrap; } private void startWeldBootstrap(ApplicationInfo applicationInfo, RootBeanDeploymentArchive rootBDA, diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index 876512cab91..a2f36f6cc1e 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -41,6 +41,7 @@ package org.glassfish.weld.services; +import com.sun.enterprise.deployment.Application; import com.sun.enterprise.deployment.BundleDescriptor; import com.sun.enterprise.deployment.EjbBundleDescriptor; import com.sun.enterprise.deployment.EjbDescriptor; @@ -155,7 +156,7 @@ public void aroundInject(InjectionContext injectionContext) { String targetClassName = targetClass.getName(); Object target = injectionContext.getTarget(); - if ( isInterceptor( targetClass ) + if ( isInterceptor( targetClass ) && !(bundleContext instanceof Application) && (componentEnv != null && !componentEnv.equals(injectionEnv)) ) { // Resources injected into interceptors must come from the environment in which the interceptor is // intercepting, not the environment in which the interceptor resides (for everything else!) @@ -214,7 +215,7 @@ public void aroundInject(InjectionContext injectionContext) { } else { injectionManager.injectInstance(target, compEnvManager.getComponentEnvId(injectionEnv),false); } - } else { + } else if (!(bundleContext instanceof Application)){ if ( target == null ) { injectionManager.injectClass(targetClass, injectionEnv, false); } else { @@ -234,7 +235,7 @@ public void aroundInject(InjectionContext injectionContext) { @Override public void registerInjectionTarget(InjectionTarget injectionTarget, AnnotatedType annotatedType) { - if ( bundleContext instanceof EjbBundleDescriptor ) { + if ( bundleContext instanceof EjbBundleDescriptor || bundleContext instanceof Application ) { // we can't handle validting producer fields for ejb bundles because the JNDI environment is not setup // yet for ejbs and so we can't get the correct JndiNameEnvironment to call getInjectionInfoByClass. // getInjectionInfoByClass caches the results and so causes subsequent calls to return invalid information. diff --git a/appserver/web/weld-integration/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable b/appserver/web/weld-integration/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable new file mode 100644 index 00000000000..de4c117de04 --- /dev/null +++ b/appserver/web/weld-integration/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable @@ -0,0 +1 @@ +org.glassfish.weld.JaxRSJsonContextResolver diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java index b3eb8bcb7cc..f354c1e26f5 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java @@ -212,14 +212,7 @@ public class ApplicationLifecycle implements Deployment, PostConstruct { protected Logger logger = KernelLoggerInfo.getLogger(); final private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(ApplicationLifecycle.class); - private final ThreadLocal> currentDeploymentContext // - = new ThreadLocal>() { - - @Override - protected Deque initialValue() { - return new ArrayDeque<>(5); - } - }; + private final ThreadLocal currentDeploymentContext = new ThreadLocal<>(); protected DeploymentLifecycleProbeProvider deploymentLifecycleProbeProvider = null; @@ -291,7 +284,6 @@ public ApplicationDeployment prepare(Collection sniffers, fin events.send(new Event<>(Deployment.DEPLOYMENT_START, context), false); eventSpan.close(); - currentDeploymentContext.get().push(context); final ActionReport report = context.getActionReport(); final DeployCommandParameters commandParams = context.getCommandParameters(DeployCommandParameters.class); final String appName = commandParams.name(); @@ -358,6 +350,7 @@ public void actOn(Logger logger) { } }; + currentDeploymentContext.set(context); try (DeploymentSpan topSpan = tracing.startSpan(DeploymentTracing.AppStage.PREPARE); SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.PREPARE, "ArchiveMetadata")) { if (commandParams.origin == OpsParams.Origin.deploy @@ -604,7 +597,7 @@ public void actOn(Logger logger) { if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { context.postDeployClean(false /* not final clean-up yet */); events.send(new Event<>(Deployment.DEPLOYMENT_FAILURE, context)); - currentDeploymentContext.get().pop(); + currentDeploymentContext.remove(); } } ApplicationDeployment depl = new ApplicationDeployment(appInfo, context); @@ -625,6 +618,7 @@ public void initialize(ApplicationInfo appInfo, Collection sn // time the containers are set up, all the modules have been prepared in their // associated engines and the application info is created and registered if (loadOnCurrentInstance(context)) { + currentDeploymentContext.set(context); try (SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.INITIALIZE)){ notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context); appInfo.initialize(); @@ -646,9 +640,9 @@ public void initialize(ApplicationInfo appInfo, Collection sn } else { events.send(new Event<>(Deployment.DEPLOYMENT_SUCCESS, appInfo)); } + currentDeploymentContext.remove(); } } - currentDeploymentContext.get().pop(); } @Override @@ -2713,6 +2707,6 @@ public Thread newThread(Runnable r) { @Override public ExtendedDeploymentContext getCurrentDeploymentContext() { - return currentDeploymentContext.get().peek(); + return currentDeploymentContext.get(); } } diff --git a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java index 235ecdcc119..573f185fa7a 100644 --- a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java +++ b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java @@ -289,7 +289,7 @@ public synchronized ClassLoader getClassLoader(boolean sharable) { // return the final classloader if (sharableTemp != null && sharableTemp.get() != cloader) { try { - PreDestroy.class.cast(sharableTemp).preDestroy(); + PreDestroy.class.cast(sharableTemp.get()).preDestroy(); } catch (Exception e) { // ignore, the classloader does not need to be destroyed } From 2555d001af09ec93786e70554c2ec4169ea08619 Mon Sep 17 00:00:00 2001 From: lprimak Date: Sat, 22 Mar 2025 00:47:00 -0500 Subject: [PATCH 02/32] exclude RAR and EJB-JAR modules from WAR/EAR-lib wiring to comply with the SPEC --- .../org/glassfish/weld/DeploymentImpl.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java index 7c14b890c05..4a5e403291f 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java @@ -315,12 +315,16 @@ public void scanArchive(ReadableArchive archive, Collection ejbs, * Deployment. */ public void buildDeploymentGraph() { + Set ejbModuleAndRarBDAs = new HashSet<>(); + // Make jars accessible to each other - Example: // /ejb1.jar <----> /ejb2.jar // If there are any application (/lib) jars, make them accessible for (RootBeanDeploymentArchive ejbRootBda : ejbRootBdas) { BeanDeploymentArchive ejbModuleBda = ejbRootBda.getModuleBda(); + ejbModuleAndRarBDAs.add(ejbRootBda); + ejbModuleAndRarBDAs.add(ejbModuleBda); boolean modifiedArchive = false; for (RootBeanDeploymentArchive otherEjbRootBda : ejbRootBdas) { @@ -347,6 +351,8 @@ public void buildDeploymentGraph() { // Make rars accessible to ejbs for (RootBeanDeploymentArchive rarRootBda : rarRootBdas) { BeanDeploymentArchive rarModuleBda = rarRootBda.getModuleBda(); + ejbModuleAndRarBDAs.add(rarRootBda); + ejbModuleAndRarBDAs.add(rarModuleBda); ejbRootBda.getBeanDeploymentArchives().add(rarRootBda); ejbRootBda.getBeanDeploymentArchives().add(rarModuleBda); ejbModuleBda.getBeanDeploymentArchives().add(rarRootBda); @@ -398,8 +404,9 @@ public void buildDeploymentGraph() { beanDeploymentArchives.stream() .filter(RootBeanDeploymentArchive.class::isInstance) .map(RootBeanDeploymentArchive.class::cast) - .forEach(bda -> recursivelyAdd(bda.getBeanDeploymentArchives(), warModuleBda, seen)); - recursivelyAdd(beanDeploymentArchives, warModuleBda, seen); + .forEach(bda -> + recursivelyAdd(bda.getBeanDeploymentArchives(), warModuleBda, seen, ejbModuleAndRarBDAs)); + recursivelyAdd(beanDeploymentArchives, warModuleBda, seen, ejbModuleAndRarBDAs); libJarRootBda.getBeanDeploymentArchives().add(warRootBda); libJarModuleBda.getBeanDeploymentArchives().add(warRootBda); libJarRootBda.getBeanDeploymentArchives().add(warModuleBda); @@ -460,11 +467,12 @@ private void addDependentBdas() { } } - private void recursivelyAdd(Collection bdas, BeanDeploymentArchive bda, Set seen) { + private void recursivelyAdd(Collection bdas, BeanDeploymentArchive bda, Set seen, + Set excluded) { for (BeanDeploymentArchive subBda : new LinkedHashSet<>(bdas)) { - if (seen.add(subBda)) { + if (seen.add(subBda) && !excluded.contains(subBda)) { subBda.getBeanDeploymentArchives().add(bda); - recursivelyAdd(subBda.getBeanDeploymentArchives(), bda, seen); + recursivelyAdd(subBda.getBeanDeploymentArchives(), bda, seen, excluded); } } } From e4d1c0505f5d16625e660a87f0ae9d3374538baf Mon Sep 17 00:00:00 2001 From: lprimak Date: Wed, 26 Mar 2025 17:23:35 -0500 Subject: [PATCH 03/32] added fish.payara.war-beans-visible-in-ear-libs system / app property --- .../org/glassfish/weld/DeploymentImpl.java | 27 +++++++++++-------- .../java/org/glassfish/weld/WeldDeployer.java | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java index 4a5e403291f..9837548f345 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java @@ -46,6 +46,7 @@ import static java.util.logging.Level.WARNING; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; +import static org.glassfish.weld.WeldDeployer.MAKE_WARS_VISIBLE_IN_EAR_LIBS; import static org.glassfish.weld.connector.WeldUtils.*; import java.io.ByteArrayInputStream; @@ -400,17 +401,21 @@ public void buildDeploymentGraph() { warModuleBda.getBeanDeploymentArchives().add(libJarModuleBda); // make WAR's BDAs accessible to libJar BDAs - Set seen = Collections.newSetFromMap(new IdentityHashMap<>()); - beanDeploymentArchives.stream() - .filter(RootBeanDeploymentArchive.class::isInstance) - .map(RootBeanDeploymentArchive.class::cast) - .forEach(bda -> - recursivelyAdd(bda.getBeanDeploymentArchives(), warModuleBda, seen, ejbModuleAndRarBDAs)); - recursivelyAdd(beanDeploymentArchives, warModuleBda, seen, ejbModuleAndRarBDAs); - libJarRootBda.getBeanDeploymentArchives().add(warRootBda); - libJarModuleBda.getBeanDeploymentArchives().add(warRootBda); - libJarRootBda.getBeanDeploymentArchives().add(warModuleBda); - libJarModuleBda.getBeanDeploymentArchives().add(warModuleBda); + boolean makeWarBDAsAccessibleToEARLibs = Boolean.parseBoolean(context.getAppProps() + .getProperty(MAKE_WARS_VISIBLE_IN_EAR_LIBS)) || Boolean.getBoolean(MAKE_WARS_VISIBLE_IN_EAR_LIBS); + if (makeWarBDAsAccessibleToEARLibs) { + Set seen = Collections.newSetFromMap(new IdentityHashMap<>()); + beanDeploymentArchives.stream() + .filter(RootBeanDeploymentArchive.class::isInstance) + .map(RootBeanDeploymentArchive.class::cast) + .forEach(bda -> + recursivelyAdd(bda.getBeanDeploymentArchives(), warModuleBda, seen, ejbModuleAndRarBDAs)); + recursivelyAdd(beanDeploymentArchives, warModuleBda, seen, ejbModuleAndRarBDAs); + libJarRootBda.getBeanDeploymentArchives().add(warRootBda); + libJarModuleBda.getBeanDeploymentArchives().add(warRootBda); + libJarRootBda.getBeanDeploymentArchives().add(warModuleBda); + libJarModuleBda.getBeanDeploymentArchives().add(warModuleBda); + } for ( BeanDeploymentArchive oneBda : warModuleBda.getBeanDeploymentArchives() ) { oneBda.getBeanDeploymentArchives().add( libJarRootBda ); diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java index 2bae45ddd6a..1c1b7a2edef 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java @@ -192,6 +192,7 @@ public class WeldDeployer extends SimpleDeployer Date: Mon, 31 Mar 2025 18:13:05 -0500 Subject: [PATCH 04/32] bugfix: dis-ambiguate by class loader if bean IDs are the same --- .../glassfish/weld/ACLSingletonProvider.java | 58 +++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java index 79f89f969a9..ca82dc42f9f 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java @@ -42,6 +42,7 @@ package org.glassfish.weld; +import org.glassfish.internal.deployment.Deployment; import org.glassfish.web.loader.WebappClassLoader; import org.jboss.weld.bootstrap.api.SingletonProvider; import org.jboss.weld.bootstrap.api.Singleton; @@ -51,6 +52,7 @@ import java.util.Map; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** @@ -86,8 +88,45 @@ public ACLSingleton create(Class expectedType) { private static class ACLSingleton implements Singleton { private final Map store = new ConcurrentHashMap<>(); - private final Map storeById = new ConcurrentHashMap<>(); + private final Map storeById = new ConcurrentHashMap<>(); private ClassLoader ccl = Globals.get(ClassLoaderHierarchy.class).getCommonClassLoader(); + private final Deployment deployment = Globals.getDefaultHabitat().getService(Deployment.class); + + private static class ClassLoaderAndId { + private final ClassLoader cl; + private final ClassLoader backupClassLoader; + private final String id; + + ClassLoaderAndId(ClassLoader cl, String id) { + this.cl = cl; + this.backupClassLoader = cl; + this.id = id; + } + + ClassLoaderAndId(ClassLoader cl, ClassLoader backupClassLoader, String id) { + this.cl = cl; + this.backupClassLoader = backupClassLoader; + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof ClassLoaderAndId)) return false; + ClassLoaderAndId that = (ClassLoaderAndId) o; + if (Objects.equals(id, that.id)) { + if (Objects.equals(cl, that.cl)) { + return true; + } + return Objects.equals(cl, that.backupClassLoader); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + } // Can't assume bootstrap loader as null. That's more of a convention. // I think either android or IBM JVM does not use null for bootstap loader @@ -108,7 +147,7 @@ public ClassLoader run() @Override public T get( String id ) { - T instance = storeById.get(id); + T instance = storeById.get(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), id)); if (instance == null) { ClassLoader acl = getClassLoader(); @@ -120,6 +159,14 @@ public T get( String id ) return instance; } + private ClassLoader getDeploymentOrContextClassLoader() { + if (deployment.getCurrentDeploymentContext() != null) { + return deployment.getCurrentDeploymentContext().getClassLoader(); + } else { + return Thread.currentThread().getContextClassLoader(); + } + } + /** * This is the most significant method of this class. This is what * distingushes it from TCCLSIngleton. It tries to obtain a class loader @@ -190,19 +237,20 @@ public ClassLoader run() @Override public boolean isSet(String id) { - return store.containsKey(getClassLoader()) || storeById.containsKey(id); + return store.containsKey(getClassLoader()) || storeById.containsKey( + new ClassLoaderAndId(getDeploymentOrContextClassLoader(), id)); } @Override public void set(String id, T object) { store.put(getClassLoader(), object); - storeById.put(id, object); + storeById.put(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader(), id), object); } @Override public void clear(String id) { store.remove(getClassLoader()); - storeById.remove(id); + storeById.remove(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader(), id)); } } } From ce9c62a3bbedd49f860d5de0eccd22849f5f193a Mon Sep 17 00:00:00 2001 From: lprimak Date: Tue, 1 Apr 2025 14:09:33 -0500 Subject: [PATCH 05/32] fixed RAR injection bug --- .../weld/services/InjectionServicesImpl.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index a2f36f6cc1e..45e08d4f6f0 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -43,6 +43,7 @@ import com.sun.enterprise.deployment.Application; import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.ConnectorDescriptor; import com.sun.enterprise.deployment.EjbBundleDescriptor; import com.sun.enterprise.deployment.EjbDescriptor; import com.sun.enterprise.deployment.InjectionCapable; @@ -156,7 +157,7 @@ public void aroundInject(InjectionContext injectionContext) { String targetClassName = targetClass.getName(); Object target = injectionContext.getTarget(); - if ( isInterceptor( targetClass ) && !(bundleContext instanceof Application) + if ( isInterceptor( targetClass ) && isValidBundleContext(false) && (componentEnv != null && !componentEnv.equals(injectionEnv)) ) { // Resources injected into interceptors must come from the environment in which the interceptor is // intercepting, not the environment in which the interceptor resides (for everything else!) @@ -215,7 +216,7 @@ public void aroundInject(InjectionContext injectionContext) { } else { injectionManager.injectInstance(target, compEnvManager.getComponentEnvId(injectionEnv),false); } - } else if (!(bundleContext instanceof Application)){ + } else if (isValidBundleContext(false)) { if ( target == null ) { injectionManager.injectClass(targetClass, injectionEnv, false); } else { @@ -235,7 +236,7 @@ public void aroundInject(InjectionContext injectionContext) { @Override public void registerInjectionTarget(InjectionTarget injectionTarget, AnnotatedType annotatedType) { - if ( bundleContext instanceof EjbBundleDescriptor || bundleContext instanceof Application ) { + if ( bundleContext instanceof EjbBundleDescriptor || !isValidBundleContext(true) ) { // we can't handle validting producer fields for ejb bundles because the JNDI environment is not setup // yet for ejbs and so we can't get the correct JndiNameEnvironment to call getInjectionInfoByClass. // getInjectionInfoByClass caches the results and so causes subsequent calls to return invalid information. @@ -475,7 +476,12 @@ private String getJndiName( String lookup, String mappedName, String name ) { return jndiName; } - + private boolean isValidBundleContext(boolean checkConnector) { + if (bundleContext instanceof Application) { + return false; + } + return !checkConnector || !(bundleContext instanceof ConnectorDescriptor); + } @Override public void cleanup() { From 6e76b700018680aadc4966a4b2f41ab0f49fee28 Mon Sep 17 00:00:00 2001 From: lprimak Date: Wed, 2 Apr 2025 22:25:55 -0400 Subject: [PATCH 06/32] another RAR fix --- .../org/glassfish/weld/services/InjectionServicesImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index 45e08d4f6f0..98eefb9310e 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -135,6 +135,10 @@ private boolean isInterceptor( Class beanClass ) { @Override public void aroundInject(InjectionContext injectionContext) { + if (!isValidBundleContext(true)) { + return; + } + try { ServiceLocator serviceLocator = Globals.getDefaultHabitat(); ComponentEnvManager compEnvManager = serviceLocator.getService(ComponentEnvManager.class); From 8c83f60dd09caf46c35a9b18afcf8aa0bb40c6fd Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 3 Apr 2025 12:41:49 -0400 Subject: [PATCH 07/32] another stab at RAR fix --- .../java/org/glassfish/weld/services/InjectionServicesImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index 98eefb9310e..cbc9920db9d 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -135,7 +135,7 @@ private boolean isInterceptor( Class beanClass ) { @Override public void aroundInject(InjectionContext injectionContext) { - if (!isValidBundleContext(true)) { + if (bundleContext instanceof ConnectorDescriptor) { return; } From e111c58e79f4cfb38d1fd67db7cd48c68ce8d412 Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 3 Apr 2025 15:55:03 -0500 Subject: [PATCH 08/32] another stab at RAR fix --- .../weld/services/InjectionServicesImpl.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index cbc9920db9d..805c2067bae 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -135,10 +135,6 @@ private boolean isInterceptor( Class beanClass ) { @Override public void aroundInject(InjectionContext injectionContext) { - if (bundleContext instanceof ConnectorDescriptor) { - return; - } - try { ServiceLocator serviceLocator = Globals.getDefaultHabitat(); ComponentEnvManager compEnvManager = serviceLocator.getService(ComponentEnvManager.class); @@ -154,14 +150,17 @@ public void aroundInject(InjectionContext injectionContext) { ManagedBeanDescriptor mbDesc = null; - JndiNameEnvironment injectionEnv = (JndiNameEnvironment) bundleContext; + JndiNameEnvironment injectionEnv = null; + if (bundleContext instanceof JndiNameEnvironment) { + injectionEnv = (JndiNameEnvironment) bundleContext; + } AnnotatedType annotatedType = injectionContext.getAnnotatedType(); Class targetClass = annotatedType.getJavaClass(); String targetClassName = targetClass.getName(); Object target = injectionContext.getTarget(); - if ( isInterceptor( targetClass ) && isValidBundleContext(false) + if ( isInterceptor( targetClass ) && isValidBundleContext(true) && (componentEnv != null && !componentEnv.equals(injectionEnv)) ) { // Resources injected into interceptors must come from the environment in which the interceptor is // intercepting, not the environment in which the interceptor resides (for everything else!) From af91b86ea49a90bc3a866d77735ee4fe0d39dee3 Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 3 Apr 2025 22:42:52 -0500 Subject: [PATCH 09/32] RAR issue - fixed based on the reproducer --- .../java/org/glassfish/weld/services/InjectionServicesImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index 805c2067bae..f80e69fd3ab 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -219,7 +219,7 @@ public void aroundInject(InjectionContext injectionContext) { } else { injectionManager.injectInstance(target, compEnvManager.getComponentEnvId(injectionEnv),false); } - } else if (isValidBundleContext(false)) { + } else if (isValidBundleContext(true)) { if ( target == null ) { injectionManager.injectClass(targetClass, injectionEnv, false); } else { From a07e85c5f18b08572552bbc43323ad9ef60da093 Mon Sep 17 00:00:00 2001 From: lprimak Date: Fri, 4 Apr 2025 00:55:57 -0500 Subject: [PATCH 10/32] RAR code cleanup --- .../weld/services/InjectionServicesImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java index f80e69fd3ab..f7833d82189 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/InjectionServicesImpl.java @@ -160,7 +160,7 @@ public void aroundInject(InjectionContext injectionContext) { String targetClassName = targetClass.getName(); Object target = injectionContext.getTarget(); - if ( isInterceptor( targetClass ) && isValidBundleContext(true) + if ( isInterceptor( targetClass ) && isValidBundleContext() && (componentEnv != null && !componentEnv.equals(injectionEnv)) ) { // Resources injected into interceptors must come from the environment in which the interceptor is // intercepting, not the environment in which the interceptor resides (for everything else!) @@ -219,7 +219,7 @@ public void aroundInject(InjectionContext injectionContext) { } else { injectionManager.injectInstance(target, compEnvManager.getComponentEnvId(injectionEnv),false); } - } else if (isValidBundleContext(true)) { + } else if (isValidBundleContext()) { if ( target == null ) { injectionManager.injectClass(targetClass, injectionEnv, false); } else { @@ -239,7 +239,7 @@ public void aroundInject(InjectionContext injectionContext) { @Override public void registerInjectionTarget(InjectionTarget injectionTarget, AnnotatedType annotatedType) { - if ( bundleContext instanceof EjbBundleDescriptor || !isValidBundleContext(true) ) { + if ( bundleContext instanceof EjbBundleDescriptor || !isValidBundleContext() ) { // we can't handle validting producer fields for ejb bundles because the JNDI environment is not setup // yet for ejbs and so we can't get the correct JndiNameEnvironment to call getInjectionInfoByClass. // getInjectionInfoByClass caches the results and so causes subsequent calls to return invalid information. @@ -479,11 +479,11 @@ private String getJndiName( String lookup, String mappedName, String name ) { return jndiName; } - private boolean isValidBundleContext(boolean checkConnector) { - if (bundleContext instanceof Application) { + private boolean isValidBundleContext() { + if (bundleContext instanceof Application || bundleContext instanceof ConnectorDescriptor) { return false; } - return !checkConnector || !(bundleContext instanceof ConnectorDescriptor); + return true; } @Override From 95592f8ec6508bb6c35f420e97113183206e134d Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 7 Apr 2025 12:15:35 -0500 Subject: [PATCH 11/32] fixed Jakarta Rest TCK test that uses custom serializer --- .../weld/JaxRSJsonContextResolver.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index eee35965191..8cb51e3b7d4 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -48,8 +48,11 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.ext.ContextResolver; import org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; import static jakarta.ws.rs.RuntimeType.SERVER; import static org.glassfish.jersey.internal.spi.AutoDiscoverable.DEFAULT_PRIORITY; @@ -65,18 +68,41 @@ public class JaxRSJsonContextResolver implements ContextResolver, ForcedAutoDiscoverable { private final Map, Jsonb> jsonbMap = new ConcurrentHashMap<>(); static final ThreadLocal> currentType = new ThreadLocal<>(); + private final List> existingResolvers; + + public JaxRSJsonContextResolver() { + this.existingResolvers = Collections.emptyList(); + } + + private JaxRSJsonContextResolver(List> existingResolvers) { + this.existingResolvers = existingResolvers; + } @Override public void configure(FeatureContext context) { - context.register(JaxRSJsonContextResolver.class); + List> resolvers = context.getConfiguration().getInstances().stream() + .filter(o -> ContextResolver.class.isAssignableFrom(o.getClass())) + .map(o -> (ContextResolver) o) + .collect(Collectors.toList()); + context.register(new JaxRSJsonContextResolver(resolvers)); } @Override public Jsonb getContext(Class type) { - return jsonbMap.computeIfAbsent(type, var -> { + return jsonbMap.computeIfAbsent(type, unused -> { currentType.set(type); try { - return JsonbBuilder.create(); + if (existingResolvers.isEmpty()) { + return JsonbBuilder.create(); + } else { + for (ContextResolver resolver : existingResolvers) { + Object result = resolver.getContext(type); + if (result instanceof Jsonb) { + return (Jsonb) result; + } + } + return JsonbBuilder.create(); + } } finally { currentType.remove(); } From 5d11d029231072a921e7b1a541d657b2346ec720 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 7 Apr 2025 15:29:13 -0500 Subject: [PATCH 12/32] JSON-B code cleanup --- .../glassfish/weld/JaxRSJsonContextResolver.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index 8cb51e3b7d4..9befaa9749d 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -92,17 +92,13 @@ public Jsonb getContext(Class type) { return jsonbMap.computeIfAbsent(type, unused -> { currentType.set(type); try { - if (existingResolvers.isEmpty()) { - return JsonbBuilder.create(); - } else { - for (ContextResolver resolver : existingResolvers) { - Object result = resolver.getContext(type); - if (result instanceof Jsonb) { - return (Jsonb) result; - } + for (ContextResolver resolver : existingResolvers) { + Object result = resolver.getContext(type); + if (result instanceof Jsonb) { + return (Jsonb) result; } - return JsonbBuilder.create(); } + return JsonbBuilder.create(); } finally { currentType.remove(); } From a571ceb711608fee63ec349886594a56c77261ef Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 7 Apr 2025 16:12:32 -0500 Subject: [PATCH 13/32] Json-B: instroduce lambda --- .../java/org/glassfish/weld/JaxRSJsonContextResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index 9befaa9749d..d4dce6dfc67 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -81,8 +81,8 @@ private JaxRSJsonContextResolver(List> existingResolvers) { @Override public void configure(FeatureContext context) { List> resolvers = context.getConfiguration().getInstances().stream() - .filter(o -> ContextResolver.class.isAssignableFrom(o.getClass())) - .map(o -> (ContextResolver) o) + .filter(ContextResolver.class::isInstance) + .map(resolver -> (ContextResolver) resolver) .collect(Collectors.toList()); context.register(new JaxRSJsonContextResolver(resolvers)); } From 42a85d162c9a088a01f00f6360cbcb5fa1849100 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 7 Apr 2025 17:15:50 -0500 Subject: [PATCH 14/32] Jakarta Web Service: update tester servlet to supported arguments --- .../webservices/monitoring/WebServiceTesterServlet.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/monitoring/WebServiceTesterServlet.java b/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/monitoring/WebServiceTesterServlet.java index e24aa0e9d8c..cdb1cb24402 100644 --- a/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/monitoring/WebServiceTesterServlet.java +++ b/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/monitoring/WebServiceTesterServlet.java @@ -543,9 +543,8 @@ private String wsImport(URL wsdlLocation) throws IOException { wsimportArgs.add(classesDir.getAbsolutePath()); wsimportArgs.add("-keep"); wsimportArgs.add(wsdlLocation.toExternalForm()); - wsimportArgs.add("-Xendorsed"); wsimportArgs.add("-target"); - wsimportArgs.add("2.1"); + wsimportArgs.add("3.0"); wsimportArgs.add("-extension"); String modulesDir = System.getProperty("com.sun.aas.installRoot") + File.separator + "modules" + File.separator; wsimportArgs.add(modulesDir + "jakarta.jws-api.jar"); From 4e2d97daec99a3c4d10a55ed5d306f9dace0eda8 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 7 Apr 2025 21:09:11 -0500 Subject: [PATCH 15/32] Web Services: restore deployment context after wstx service startup --- .../org/glassfish/webservices/WebServicesDeployer.java | 7 +++++++ .../java/org/glassfish/internal/deployment/Deployment.java | 3 +++ .../com/sun/enterprise/v3/server/ApplicationLifecycle.java | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java b/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java index d4e0a4718c0..b63e1b055b8 100644 --- a/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java +++ b/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java @@ -57,6 +57,8 @@ import org.glassfish.api.deployment.archive.WritableArchive; import org.glassfish.deployment.common.DeploymentException; import org.glassfish.internal.api.JAXRPCCodeGenFacade; +import org.glassfish.internal.deployment.Deployment; +import org.glassfish.internal.deployment.ExtendedDeploymentContext; import org.glassfish.javaee.core.deployment.JavaEEDeployer; import org.glassfish.loader.util.ASClassLoaderUtil; import org.glassfish.web.deployment.descriptor.AppListenerDescriptorImpl; @@ -105,6 +107,9 @@ public class WebServicesDeployer extends JavaEEDeployer Date: Wed, 9 Apr 2025 12:20:38 -0500 Subject: [PATCH 16/32] Revert "Web Services: restore deployment context after wstx service startup" This reverts commit 4e2d97daec99a3c4d10a55ed5d306f9dace0eda8. --- .../org/glassfish/webservices/WebServicesDeployer.java | 7 ------- .../java/org/glassfish/internal/deployment/Deployment.java | 3 --- .../com/sun/enterprise/v3/server/ApplicationLifecycle.java | 5 ----- 3 files changed, 15 deletions(-) diff --git a/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java b/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java index b63e1b055b8..d4e0a4718c0 100644 --- a/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java +++ b/appserver/webservices/jsr109-impl/src/main/java/org/glassfish/webservices/WebServicesDeployer.java @@ -57,8 +57,6 @@ import org.glassfish.api.deployment.archive.WritableArchive; import org.glassfish.deployment.common.DeploymentException; import org.glassfish.internal.api.JAXRPCCodeGenFacade; -import org.glassfish.internal.deployment.Deployment; -import org.glassfish.internal.deployment.ExtendedDeploymentContext; import org.glassfish.javaee.core.deployment.JavaEEDeployer; import org.glassfish.loader.util.ASClassLoaderUtil; import org.glassfish.web.deployment.descriptor.AppListenerDescriptorImpl; @@ -107,9 +105,6 @@ public class WebServicesDeployer extends JavaEEDeployer Date: Wed, 9 Apr 2025 12:46:49 -0500 Subject: [PATCH 17/32] more generic fix for recursive deployments (ex: WebServices/WSTX deployer) --- .../com/sun/enterprise/v3/server/ApplicationLifecycle.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java index f354c1e26f5..fed0880e980 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java @@ -1246,6 +1246,7 @@ public ModuleInfo prepareModule( // get the deployer Deployer deployer = engineInfo.getDeployer(); + ExtendedDeploymentContext savedDeploymentContext = currentDeploymentContext.get(); try (DeploymentSpan span = tracing.startSpan(TraceContext.Level.CONTAINER, engineInfo.getSniffer().getModuleType(), DeploymentTracing.AppStage.PREPARE)){ deployer.prepare(context); @@ -1260,6 +1261,10 @@ public ModuleInfo prepareModule( final ActionReport report = context.getActionReport(); report.failure(logger, "Exception while invoking " + deployer.getClass() + " prepare method", e); throw e; + } finally { + if (currentDeploymentContext.get() == null) { + currentDeploymentContext.set(savedDeploymentContext); + } } } From 356571056b187d37e9e083decb9684b7769760c1 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 14 Apr 2025 22:35:18 -0500 Subject: [PATCH 18/32] bugfix: only apply Jax-RS resolver type for CDI if it's not a class with an existing ClassLoader --- .../glassfish/weld/GlassFishWeldProvider.java | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java index c0c266e5871..f5f5ebc01ac 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java @@ -107,29 +107,23 @@ protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { @Override protected String getCallingClassName() { + String superCallingClassName = super.getCallingClassName(); if (currentType.get() != null) { - return currentType.get().getName(); - } else { - return super.getCallingClassName(); + try { + if (getBundleDescriptor().getClassLoader().loadClass(superCallingClassName).getClassLoader() == null) { + return currentType.get().getName(); + } + } catch (ClassNotFoundException | NullPointerException e) { + } } + return superCallingClassName; } } @Override public CDI getCDI() { try { - BundleDescriptor bundle = null; - Object componentEnv = invocationManager.getCurrentInvocation().getJNDIEnvironment(); - if( componentEnv instanceof EjbDescriptor) { - bundle = (BundleDescriptor) - ((EjbDescriptor) componentEnv).getEjbBundleDescriptor(). - getModuleDescriptor().getDescriptor(); - - } else if( componentEnv instanceof WebBundleDescriptor) { - bundle = (BundleDescriptor) componentEnv; - } - - BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(bundle); + BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(getBundleDescriptor()); if (bda == null) { return new GlassFishEnhancedWeld(); } else { @@ -143,4 +137,18 @@ public CDI getCDI() { throw throwable; } } + + private static BundleDescriptor getBundleDescriptor() { + BundleDescriptor bundle = null; + Object componentEnv = invocationManager.getCurrentInvocation().getJNDIEnvironment(); + if( componentEnv instanceof EjbDescriptor) { + bundle = (BundleDescriptor) + ((EjbDescriptor) componentEnv).getEjbBundleDescriptor(). + getModuleDescriptor().getDescriptor(); + + } else if( componentEnv instanceof WebBundleDescriptor) { + bundle = (BundleDescriptor) componentEnv; + } + return bundle; + } } From 5bae52c518b29031314e92de8586d001a7973005 Mon Sep 17 00:00:00 2001 From: lprimak Date: Tue, 15 Apr 2025 18:49:15 -0500 Subject: [PATCH 19/32] one more guess at Rest integratino issues --- .../glassfish/weld/GlassFishWeldProvider.java | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java index f5f5ebc01ac..f8d68addbd6 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java @@ -49,10 +49,12 @@ import org.jboss.weld.Container; import org.jboss.weld.SimpleCDI; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; +import org.jboss.weld.logging.BeanManagerLogger; import org.jboss.weld.manager.BeanManagerImpl; import jakarta.enterprise.inject.spi.CDI; import jakarta.enterprise.inject.spi.CDIProvider; +import java.util.HashSet; import java.util.Map; import java.util.Set; import static org.glassfish.weld.JaxRSJsonContextResolver.currentType; @@ -65,11 +67,15 @@ public class GlassFishWeldProvider implements CDIProvider { private static final InvocationManager invocationManager = Globals.get(InvocationManager.class); private static class GlassFishEnhancedWeld extends SimpleCDI { + private final Set knownClassNames; + GlassFishEnhancedWeld() { + knownClassNames = new HashSet<>(super.knownClassNames); } GlassFishEnhancedWeld(String contextId) { super(contextId == null ? Container.instance() : Container.instance(contextId)); + knownClassNames = new HashSet<>(super.knownClassNames); } @Override @@ -107,17 +113,43 @@ protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { @Override protected String getCallingClassName() { - String superCallingClassName = super.getCallingClassName(); + String superCallingClassName = _getCallingClassName(); if (currentType.get() != null) { - try { - if (getBundleDescriptor().getClassLoader().loadClass(superCallingClassName).getClassLoader() == null) { + while (true) { + try { + while (getBundleDescriptor().getClassLoader().loadClass(superCallingClassName).getClassLoader() != + getBundleDescriptor().getClassLoader()) { + knownClassNames.add(superCallingClassName); + superCallingClassName = _getCallingClassName(); + } + break; + } catch (ClassNotFoundException | NullPointerException | IllegalStateException e) { return currentType.get().getName(); } - } catch (ClassNotFoundException | NullPointerException e) { } } return superCallingClassName; } + + /** + * copied from Weld because knownClassNames is not modifiable + * @return + */ + private String _getCallingClassName() { + boolean outerSubclassReached = false; + for (StackTraceElement element : Thread.currentThread().getStackTrace()) { + // the method call that leads to the first invocation of this class or its subclass is considered the caller + if (!knownClassNames.contains(element.getClassName())) { + if (outerSubclassReached) { + return element.getClassName(); + } + } else { + outerSubclassReached = true; + } + } + throw BeanManagerLogger.LOG.unableToIdentifyBeanManager(); + } + } @Override From 46a6d0a89c290ef30a5311492e81a598c9f4b0f2 Mon Sep 17 00:00:00 2001 From: lprimak Date: Wed, 23 Apr 2025 15:42:55 -0500 Subject: [PATCH 20/32] add context providers registered via @Provider annotation --- .../java/org/glassfish/weld/JaxRSJsonContextResolver.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index d4dce6dfc67..99bbbc4607a 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -84,6 +84,10 @@ public void configure(FeatureContext context) { .filter(ContextResolver.class::isInstance) .map(resolver -> (ContextResolver) resolver) .collect(Collectors.toList()); + context.getConfiguration().getClasses().stream() + .filter(ContextResolver.class::isAssignableFrom) + .map(ContextResolver.class::cast) + .forEach(resolvers::add); context.register(new JaxRSJsonContextResolver(resolvers)); } From bdb0398303463c1f6297370ee96fc38c73bb958b Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 24 Apr 2025 00:08:14 -0500 Subject: [PATCH 21/32] working interceptor --- .../glassfish/weld/JaxRSJsonContextResolver.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index 99bbbc4607a..a7ea405c4f5 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -51,6 +51,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import static jakarta.ws.rs.RuntimeType.SERVER; @@ -85,9 +86,17 @@ public void configure(FeatureContext context) { .map(resolver -> (ContextResolver) resolver) .collect(Collectors.toList()); context.getConfiguration().getClasses().stream() - .filter(ContextResolver.class::isAssignableFrom) - .map(ContextResolver.class::cast) - .forEach(resolvers::add); + .filter(ContextResolver.class::isAssignableFrom) + .map(cls -> { + try { + return cls.getDeclaredConstructor().newInstance(); + } catch (ReflectiveOperationException e) { + return null; + } + }) + .filter(Objects::nonNull) + .map(ContextResolver.class::cast) + .forEach(resolvers::add); context.register(new JaxRSJsonContextResolver(resolvers)); } From f8f05f7ea66b71a96fa24880c4721c4ea424c473 Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 24 Apr 2025 00:47:28 -0500 Subject: [PATCH 22/32] refactor --- .../weld/JaxRSJsonContextResolver.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index a7ea405c4f5..e141b45c1dd 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -40,6 +40,7 @@ package org.glassfish.weld; import jakarta.annotation.Priority; +import jakarta.inject.Inject; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; import jakarta.ws.rs.ConstrainedTo; @@ -47,6 +48,7 @@ import jakarta.ws.rs.core.FeatureContext; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.ext.ContextResolver; +import org.glassfish.jersey.internal.inject.InjectionManager; import org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable; import java.util.Collections; import java.util.List; @@ -70,13 +72,20 @@ public class JaxRSJsonContextResolver implements ContextResolver, ForcedA private final Map, Jsonb> jsonbMap = new ConcurrentHashMap<>(); static final ThreadLocal> currentType = new ThreadLocal<>(); private final List> existingResolvers; + private final List>> existingResolverClasses; + + @Inject + InjectionManager injectionManager; public JaxRSJsonContextResolver() { this.existingResolvers = Collections.emptyList(); + this.existingResolverClasses = Collections.emptyList(); } - private JaxRSJsonContextResolver(List> existingResolvers) { + private JaxRSJsonContextResolver(List> existingResolvers, + List>> existingResolverClasses) { this.existingResolvers = existingResolvers; + this.existingResolverClasses = existingResolverClasses; } @Override @@ -85,24 +94,18 @@ public void configure(FeatureContext context) { .filter(ContextResolver.class::isInstance) .map(resolver -> (ContextResolver) resolver) .collect(Collectors.toList()); - context.getConfiguration().getClasses().stream() + @SuppressWarnings("unchecked") + var resolverClasses = context.getConfiguration().getClasses().stream() .filter(ContextResolver.class::isAssignableFrom) - .map(cls -> { - try { - return cls.getDeclaredConstructor().newInstance(); - } catch (ReflectiveOperationException e) { - return null; - } - }) - .filter(Objects::nonNull) - .map(ContextResolver.class::cast) - .forEach(resolvers::add); - context.register(new JaxRSJsonContextResolver(resolvers)); + .map(cls -> (Class>) cls) + .collect(Collectors.toList()); + context.register(new JaxRSJsonContextResolver(resolvers, resolverClasses)); } @Override public Jsonb getContext(Class type) { return jsonbMap.computeIfAbsent(type, unused -> { + instantiateResolverClasses(); currentType.set(type); try { for (ContextResolver resolver : existingResolvers) { @@ -117,4 +120,13 @@ public Jsonb getContext(Class type) { } }); } + + private void instantiateResolverClasses() { + if (!existingResolverClasses.isEmpty()) { + existingResolverClasses.stream().map(injectionManager::getInstance) + .filter(Objects::nonNull) + .forEach(existingResolvers::add); + } + existingResolverClasses.clear(); + } } From 2f261bbe7ac6b00a2d6927b1345c2a647ffcdf1c Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 24 Apr 2025 12:23:09 -0500 Subject: [PATCH 23/32] review comment - fixed confusing line --- .../main/java/org/glassfish/weld/JaxRSJsonContextResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index e141b45c1dd..8a06849bfd2 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -126,7 +126,7 @@ private void instantiateResolverClasses() { existingResolverClasses.stream().map(injectionManager::getInstance) .filter(Objects::nonNull) .forEach(existingResolvers::add); + existingResolverClasses.clear(); } - existingResolverClasses.clear(); } } From f9cde87ff2e7bcf36010143f5725fa72e140a869 Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 24 Apr 2025 13:39:42 -0500 Subject: [PATCH 24/32] fallback to any type from the proper BDA if the registered type is a basic type or not loaded by the application --- .../java/org/glassfish/weld/GlassFishWeldProvider.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java index f8d68addbd6..ab1958b395b 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java @@ -124,7 +124,12 @@ protected String getCallingClassName() { } break; } catch (ClassNotFoundException | NullPointerException | IllegalStateException e) { - return currentType.get().getName(); + if (currentType.get().getClassLoader() != null) { + return currentType.get().getName(); + } else { + BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(getBundleDescriptor()); + return bda.getBeanClasses().stream().findAny().orElse(superCallingClassName); + } } } } From 86704b9670a2493bddbc4ced9e07e112a8cae282 Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 24 Apr 2025 13:55:34 -0500 Subject: [PATCH 25/32] fixed class loader check --- .../src/main/java/org/glassfish/weld/GlassFishWeldProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java index ab1958b395b..746e3e62ffd 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java @@ -124,7 +124,7 @@ protected String getCallingClassName() { } break; } catch (ClassNotFoundException | NullPointerException | IllegalStateException e) { - if (currentType.get().getClassLoader() != null) { + if (currentType.get().getClassLoader() == getBundleDescriptor().getClassLoader()) { return currentType.get().getName(); } else { BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(getBundleDescriptor()); From 0cb1b80497b2691960d0d2f15d50f37b37d5a2ad Mon Sep 17 00:00:00 2001 From: lprimak Date: Fri, 25 Apr 2025 14:06:49 -0500 Subject: [PATCH 26/32] added backup find of Weld manager instance in case none of the ClassLoaders match, which may be the case for async servlets and Rest --- .../org/glassfish/weld/ACLSingletonProvider.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java index ca82dc42f9f..1f61255f72b 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java @@ -117,7 +117,11 @@ public boolean equals(Object o) { if (Objects.equals(cl, that.cl)) { return true; } - return Objects.equals(cl, that.backupClassLoader); + if (backupClassLoader != null) { + return Objects.equals(cl, that.backupClassLoader); + } else { + return true; + } } return false; } @@ -148,8 +152,10 @@ public ClassLoader run() public T get( String id ) { T instance = storeById.get(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), id)); - if (instance == null) - { + if (instance == null) { + instance = storeById.get(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), null, id)); + } + if (instance == null) { ClassLoader acl = getClassLoader(); instance = store.get(acl); if (instance == null) { @@ -238,7 +244,7 @@ public ClassLoader run() @Override public boolean isSet(String id) { return store.containsKey(getClassLoader()) || storeById.containsKey( - new ClassLoaderAndId(getDeploymentOrContextClassLoader(), id)); + new ClassLoaderAndId(getDeploymentOrContextClassLoader(), null, id)); } @Override From 849492898e825c86ced686f2c103fe3f17554e79 Mon Sep 17 00:00:00 2001 From: lprimak Date: Fri, 25 Apr 2025 14:47:41 -0500 Subject: [PATCH 27/32] cleanup --- .../glassfish/weld/ACLSingletonProvider.java | 77 +++++++++---------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java index 1f61255f72b..b32704fec2f 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java @@ -92,45 +92,41 @@ private static class ACLSingleton implements Singleton { private ClassLoader ccl = Globals.get(ClassLoaderHierarchy.class).getCommonClassLoader(); private final Deployment deployment = Globals.getDefaultHabitat().getService(Deployment.class); - private static class ClassLoaderAndId { - private final ClassLoader cl; - private final ClassLoader backupClassLoader; - private final String id; + private static class ClassLoaderAndId { + private final ClassLoader cl; + private final ClassLoader backupClassLoader; + private final String id; - ClassLoaderAndId(ClassLoader cl, String id) { - this.cl = cl; - this.backupClassLoader = cl; - this.id = id; - } + ClassLoaderAndId(String id) { + this.id = id; + this.cl = this.backupClassLoader = null; + } - ClassLoaderAndId(ClassLoader cl, ClassLoader backupClassLoader, String id) { - this.cl = cl; - this.backupClassLoader = backupClassLoader; - this.id = id; - } + ClassLoaderAndId(String id, ClassLoader cl) { + this.id = id; + this.cl = this.backupClassLoader = cl; + } - @Override - public boolean equals(Object o) { - if (!(o instanceof ClassLoaderAndId)) return false; - ClassLoaderAndId that = (ClassLoaderAndId) o; - if (Objects.equals(id, that.id)) { - if (Objects.equals(cl, that.cl)) { - return true; - } - if (backupClassLoader != null) { - return Objects.equals(cl, that.backupClassLoader); - } else { - return true; - } - } - return false; - } + ClassLoaderAndId(String id, ClassLoader cl, ClassLoader backupClassLoader) { + this.id = id; + this.cl = cl; + this.backupClassLoader = backupClassLoader; + } - @Override - public int hashCode() { - return Objects.hash(id); - } - } + @Override + public boolean equals(Object o) { + if (!(o instanceof ClassLoaderAndId)) return false; + ClassLoaderAndId that = (ClassLoaderAndId) o; + return Objects.equals(id, that.id) + && (cl == null || Objects.equals(cl, that.cl) + || Objects.equals(cl, that.backupClassLoader)); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + } // Can't assume bootstrap loader as null. That's more of a convention. // I think either android or IBM JVM does not use null for bootstap loader @@ -151,9 +147,9 @@ public ClassLoader run() @Override public T get( String id ) { - T instance = storeById.get(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), id)); + T instance = storeById.get(new ClassLoaderAndId(id, getDeploymentOrContextClassLoader())); if (instance == null) { - instance = storeById.get(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), null, id)); + instance = storeById.get(new ClassLoaderAndId(id)); } if (instance == null) { ClassLoader acl = getClassLoader(); @@ -243,20 +239,19 @@ public ClassLoader run() @Override public boolean isSet(String id) { - return store.containsKey(getClassLoader()) || storeById.containsKey( - new ClassLoaderAndId(getDeploymentOrContextClassLoader(), null, id)); + return store.containsKey(getClassLoader()) || storeById.containsKey(new ClassLoaderAndId(id)); } @Override public void set(String id, T object) { store.put(getClassLoader(), object); - storeById.put(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader(), id), object); + storeById.put(new ClassLoaderAndId(id, getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader()), object); } @Override public void clear(String id) { store.remove(getClassLoader()); - storeById.remove(new ClassLoaderAndId(getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader(), id)); + storeById.remove(new ClassLoaderAndId(id, getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader())); } } } From 0cf55b0bfdc2df3278d46d7a0f6304e505727fb6 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 28 Apr 2025 20:54:16 -0500 Subject: [PATCH 28/32] reworked and simplified CDI BeanManager find algorithm --- .../iiop/impl/POARemoteReferenceFactory.java | 11 ++-- .../glassfish/weld/GlassFishWeldProvider.java | 50 +++++++------------ .../weld/JaxRSJsonContextResolver.java | 16 ++---- 3 files changed, 29 insertions(+), 48 deletions(-) diff --git a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java index 1ed18a5c144..418fc6d61c9 100755 --- a/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java +++ b/appserver/orb/orb-iiop/src/main/java/org/glassfish/enterprise/iiop/impl/POARemoteReferenceFactory.java @@ -37,13 +37,14 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2018-2021] [Payara Foundation and/or its affiliates] +// Portions Copyright [2018-2025] [Payara Foundation and/or its affiliates] package org.glassfish.enterprise.iiop.impl; import jakarta.ejb.NoSuchObjectLocalException; +import java.lang.ref.WeakReference; import java.rmi.Remote; import java.security.AccessController ; @@ -135,7 +136,7 @@ public final class POARemoteReferenceFactory extends org.omg.CORBA.LocalObject private EjbContainerFacade container; private EjbDescriptor ejbDescriptor; - private ClassLoader appClassLoader; + private WeakReference appClassLoader; private ORB orb; private POAProtocolMgr protocolMgr; @@ -180,7 +181,7 @@ public final class POARemoteReferenceFactory extends org.omg.CORBA.LocalObject this.ejbDescriptor = container.getEjbDescriptor(); this.isRemoteHomeView = remoteHomeView; - appClassLoader = container.getClassLoader(); + appClassLoader = new WeakReference<>(container.getClassLoader()); // NOTE: ReferenceFactory creation happens in setRepositoryIds. } @@ -217,12 +218,12 @@ public void setRepositoryIds(Class homeIntf, Class remoteIntf) // Home ejbHomeStubFactory = sff.createStubFactory( homeIntf.getName(), false, - "", null, appClassLoader); + "", null, appClassLoader.get()); String[] ejbHomeTypeIds = ejbHomeStubFactory.getTypeIds(); ejbHomeRepositoryId = ejbHomeTypeIds[0]; ejbObjectStubFactory = sff.createStubFactory - ( remoteIntf.getName(), false, "", null, appClassLoader); + ( remoteIntf.getName(), false, "", null, appClassLoader.get()); String[] ejbObjectTypeIds = ejbObjectStubFactory.getTypeIds(); diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java index 746e3e62ffd..ad94d792c32 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/GlassFishWeldProvider.java @@ -54,10 +54,12 @@ import jakarta.enterprise.inject.spi.CDI; import jakarta.enterprise.inject.spi.CDIProvider; +import java.lang.StackWalker.StackFrame; import java.util.HashSet; import java.util.Map; import java.util.Set; -import static org.glassfish.weld.JaxRSJsonContextResolver.currentType; +import java.util.stream.Collectors; +import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; /** * @author JJ Snyder @@ -65,6 +67,7 @@ public class GlassFishWeldProvider implements CDIProvider { private static final WeldDeployer weldDeployer = Globals.get(WeldDeployer.class); private static final InvocationManager invocationManager = Globals.get(InvocationManager.class); + private static final StackWalker stackWalker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE); private static class GlassFishEnhancedWeld extends SimpleCDI { private final Set knownClassNames; @@ -113,40 +116,19 @@ protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { @Override protected String getCallingClassName() { - String superCallingClassName = _getCallingClassName(); - if (currentType.get() != null) { - while (true) { - try { - while (getBundleDescriptor().getClassLoader().loadClass(superCallingClassName).getClassLoader() != - getBundleDescriptor().getClassLoader()) { - knownClassNames.add(superCallingClassName); - superCallingClassName = _getCallingClassName(); - } - break; - } catch (ClassNotFoundException | NullPointerException | IllegalStateException e) { - if (currentType.get().getClassLoader() == getBundleDescriptor().getClassLoader()) { - return currentType.get().getName(); - } else { - BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(getBundleDescriptor()); - return bda.getBeanClasses().stream().findAny().orElse(superCallingClassName); - } - } - } - } - return superCallingClassName; - } - - /** - * copied from Weld because knownClassNames is not modifiable - * @return - */ - private String _getCallingClassName() { boolean outerSubclassReached = false; - for (StackTraceElement element : Thread.currentThread().getStackTrace()) { + BundleDescriptor bundleDescriptor = getBundleDescriptor(); + for (StackFrame element : stackWalker.walk(sf -> sf.collect(Collectors.toList()))) { // the method call that leads to the first invocation of this class or its subclass is considered the caller if (!knownClassNames.contains(element.getClassName())) { - if (outerSubclassReached) { - return element.getClassName(); + Class declaringClass = element.getDeclaringClass(); + if (outerSubclassReached && declaringClass.getClassLoader() != null) { + if (bundleDescriptor != null && declaringClass.getClassLoader() == bundleDescriptor.getClassLoader()) { + // we are in the same class loader, so this is the caller + return declaringClass.getName(); + } else { + return getAnyClassFromBundleDescriptor(declaringClass.getName()); + } } } else { outerSubclassReached = true; @@ -155,6 +137,10 @@ private String _getCallingClassName() { throw BeanManagerLogger.LOG.unableToIdentifyBeanManager(); } + private static String getAnyClassFromBundleDescriptor(String backupClassName) { + BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(getBundleDescriptor()); + return bda != null ? bda.getBeanClasses().stream().findAny().orElse(backupClassName) : backupClassName; + } } @Override diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java index 8a06849bfd2..9bc502a038d 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -70,7 +70,6 @@ @Produces(MediaType.APPLICATION_JSON) public class JaxRSJsonContextResolver implements ContextResolver, ForcedAutoDiscoverable { private final Map, Jsonb> jsonbMap = new ConcurrentHashMap<>(); - static final ThreadLocal> currentType = new ThreadLocal<>(); private final List> existingResolvers; private final List>> existingResolverClasses; @@ -106,18 +105,13 @@ public void configure(FeatureContext context) { public Jsonb getContext(Class type) { return jsonbMap.computeIfAbsent(type, unused -> { instantiateResolverClasses(); - currentType.set(type); - try { - for (ContextResolver resolver : existingResolvers) { - Object result = resolver.getContext(type); - if (result instanceof Jsonb) { - return (Jsonb) result; - } + for (ContextResolver resolver : existingResolvers) { + Object result = resolver.getContext(type); + if (result instanceof Jsonb) { + return (Jsonb) result; } - return JsonbBuilder.create(); - } finally { - currentType.remove(); } + return JsonbBuilder.create(); }); } From ea3ee830e149c685006b63aa60006d2d2482e841 Mon Sep 17 00:00:00 2001 From: lprimak Date: Thu, 1 May 2025 13:31:34 -0600 Subject: [PATCH 29/32] fixed circular reference to current deployment context --- .../v3/server/ApplicationLifecycle.java | 18 ++++++++--------- .../deployment/common/DeploymentUtils.java | 20 +++++++++++-------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java index fed0880e980..c5894174385 100644 --- a/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java +++ b/nucleus/core/kernel/src/main/java/com/sun/enterprise/v3/server/ApplicationLifecycle.java @@ -212,8 +212,6 @@ public class ApplicationLifecycle implements Deployment, PostConstruct { protected Logger logger = KernelLoggerInfo.getLogger(); final private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(ApplicationLifecycle.class); - private final ThreadLocal currentDeploymentContext = new ThreadLocal<>(); - protected DeploymentLifecycleProbeProvider deploymentLifecycleProbeProvider = null; @@ -350,7 +348,7 @@ public void actOn(Logger logger) { } }; - currentDeploymentContext.set(context); + DeploymentUtils.setCurrentDeploymentContext(context); try (DeploymentSpan topSpan = tracing.startSpan(DeploymentTracing.AppStage.PREPARE); SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.PREPARE, "ArchiveMetadata")) { if (commandParams.origin == OpsParams.Origin.deploy @@ -597,7 +595,7 @@ public void actOn(Logger logger) { if (report.getActionExitCode() != ActionReport.ExitCode.SUCCESS) { context.postDeployClean(false /* not final clean-up yet */); events.send(new Event<>(Deployment.DEPLOYMENT_FAILURE, context)); - currentDeploymentContext.remove(); + DeploymentUtils.clearCurrentDeploymentContext(); } } ApplicationDeployment depl = new ApplicationDeployment(appInfo, context); @@ -618,7 +616,7 @@ public void initialize(ApplicationInfo appInfo, Collection sn // time the containers are set up, all the modules have been prepared in their // associated engines and the application info is created and registered if (loadOnCurrentInstance(context)) { - currentDeploymentContext.set(context); + DeploymentUtils.setCurrentDeploymentContext(context); try (SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.INITIALIZE)){ notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context); appInfo.initialize(); @@ -640,7 +638,7 @@ public void initialize(ApplicationInfo appInfo, Collection sn } else { events.send(new Event<>(Deployment.DEPLOYMENT_SUCCESS, appInfo)); } - currentDeploymentContext.remove(); + DeploymentUtils.clearCurrentDeploymentContext(); } } } @@ -1246,7 +1244,7 @@ public ModuleInfo prepareModule( // get the deployer Deployer deployer = engineInfo.getDeployer(); - ExtendedDeploymentContext savedDeploymentContext = currentDeploymentContext.get(); + ExtendedDeploymentContext savedDeploymentContext = DeploymentUtils.getCurrentDeploymentContext(); try (DeploymentSpan span = tracing.startSpan(TraceContext.Level.CONTAINER, engineInfo.getSniffer().getModuleType(), DeploymentTracing.AppStage.PREPARE)){ deployer.prepare(context); @@ -1262,8 +1260,8 @@ public ModuleInfo prepareModule( report.failure(logger, "Exception while invoking " + deployer.getClass() + " prepare method", e); throw e; } finally { - if (currentDeploymentContext.get() == null) { - currentDeploymentContext.set(savedDeploymentContext); + if (getCurrentDeploymentContext() == null) { + DeploymentUtils.setCurrentDeploymentContext(savedDeploymentContext); } } } @@ -2712,6 +2710,6 @@ public Thread newThread(Runnable r) { @Override public ExtendedDeploymentContext getCurrentDeploymentContext() { - return currentDeploymentContext.get(); + return DeploymentUtils.getCurrentDeploymentContext(); } } diff --git a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentUtils.java b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentUtils.java index 9ea44d5fefb..ae86f5d23fd 100644 --- a/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentUtils.java +++ b/nucleus/deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentUtils.java @@ -55,8 +55,7 @@ import org.glassfish.api.deployment.DeploymentContext; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.classmodel.reflect.Type; -import org.glassfish.internal.api.Globals; -import org.glassfish.internal.deployment.Deployment; +import org.glassfish.internal.deployment.ExtendedDeploymentContext; import org.glassfish.loader.util.ASClassLoaderUtil; @@ -113,6 +112,7 @@ public class DeploymentUtils { private final static String DOWNLOADABLE_ARTIFACTS_KEY_PREFIX = "downloadable"; private final static String GENERATED_ARTIFACTS_KEY_PREFIX = "generated"; + private static final ThreadLocal currentDeploymentContext = new ThreadLocal<>(); private static final Map warLibraryCache = new ConcurrentHashMap<>(); public static class WarLibraryDescriptor { @@ -466,12 +466,16 @@ public static List getExternalLibraries(ReadableArchive archive) { return externalLibURIs; } - public static DeploymentContext getCurrentDeploymentContext() { - try { - return Globals.getDefaultHabitat().getService(Deployment.class).getCurrentDeploymentContext(); - } catch (Exception e) { - return null; - } + public static ExtendedDeploymentContext getCurrentDeploymentContext() { + return currentDeploymentContext.get(); + } + + public static void setCurrentDeploymentContext(ExtendedDeploymentContext context) { + currentDeploymentContext.set(context); + } + + public static void clearCurrentDeploymentContext() { + currentDeploymentContext.remove(); } public static List getWarLibraryURIs(DeploymentContext context) { From f00b096816814915928b252cde273eb5ae769a14 Mon Sep 17 00:00:00 2001 From: lprimak Date: Sun, 4 May 2025 20:27:03 -0500 Subject: [PATCH 30/32] refactor assymetric equals() code into multimap --- .../glassfish/weld/ACLSingletonProvider.java | 79 +++++++++---------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java index b32704fec2f..103296c9667 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. * - * Portions Copyright [2017-2024] Payara Foundation and/or affiliates + * Portions Copyright [2017-2025] Payara Foundation and/or affiliates */ package org.glassfish.weld; @@ -48,12 +48,17 @@ import org.jboss.weld.bootstrap.api.Singleton; import org.glassfish.internal.api.Globals; import org.glassfish.internal.api.ClassLoaderHierarchy; +import org.jboss.weld.util.collections.Multimap; +import org.jboss.weld.util.collections.SetMultimap; +import java.util.Collection; import java.util.Map; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; +import static org.glassfish.weld.ACLSingletonProvider.ACLSingleton.ValueAndClassLoaders.findByClassLoader; +import static org.glassfish.weld.ACLSingletonProvider.ACLSingleton.ValueAndClassLoaders.findByIdOnly; /** * Singleton provider that uses Application ClassLoader to differentiate @@ -85,47 +90,38 @@ public ACLSingleton create(Class expectedType) { return new ACLSingleton(); } - private static class ACLSingleton implements Singleton { + static class ACLSingleton implements Singleton { private final Map store = new ConcurrentHashMap<>(); - private final Map storeById = new ConcurrentHashMap<>(); + private final Multimap> storeById = SetMultimap.newConcurrentSetMultimap(); private ClassLoader ccl = Globals.get(ClassLoaderHierarchy.class).getCommonClassLoader(); private final Deployment deployment = Globals.getDefaultHabitat().getService(Deployment.class); + static final class ValueAndClassLoaders { + final TT value; + final ClassLoader classLoader; + final ClassLoader backupClassLoader; - private static class ClassLoaderAndId { - private final ClassLoader cl; - private final ClassLoader backupClassLoader; - private final String id; - - ClassLoaderAndId(String id) { - this.id = id; - this.cl = this.backupClassLoader = null; - } - - ClassLoaderAndId(String id, ClassLoader cl) { - this.id = id; - this.cl = this.backupClassLoader = cl; - } - - ClassLoaderAndId(String id, ClassLoader cl, ClassLoader backupClassLoader) { - this.id = id; - this.cl = cl; - this.backupClassLoader = backupClassLoader; - } + public ValueAndClassLoaders(TT value, ClassLoader classLoader, ClassLoader backupClassLoader) { + this.value = value; + this.classLoader = classLoader; + this.backupClassLoader = backupClassLoader; + } - @Override - public boolean equals(Object o) { - if (!(o instanceof ClassLoaderAndId)) return false; - ClassLoaderAndId that = (ClassLoaderAndId) o; - return Objects.equals(id, that.id) - && (cl == null || Objects.equals(cl, that.cl) - || Objects.equals(cl, that.backupClassLoader)); - } + public static T findByClassLoader(Collection> values, ClassLoader classLoader) { + return values.stream() + .filter(v -> Objects.equals(v.classLoader, classLoader) + || Objects.equals(v.backupClassLoader, classLoader)) + .findAny() + .map(v -> v.value) + .orElse(null); + } - @Override - public int hashCode() { - return Objects.hash(id); - } + public static T findByIdOnly(Collection> values) { + return values.stream() + .findAny() + .map(v -> v.value) + .orElse(null); + } } // Can't assume bootstrap loader as null. That's more of a convention. @@ -147,9 +143,9 @@ public ClassLoader run() @Override public T get( String id ) { - T instance = storeById.get(new ClassLoaderAndId(id, getDeploymentOrContextClassLoader())); + T instance = findByClassLoader(storeById.get(id), getDeploymentOrContextClassLoader()); if (instance == null) { - instance = storeById.get(new ClassLoaderAndId(id)); + instance = findByIdOnly(storeById.get(id)); } if (instance == null) { ClassLoader acl = getClassLoader(); @@ -239,19 +235,22 @@ public ClassLoader run() @Override public boolean isSet(String id) { - return store.containsKey(getClassLoader()) || storeById.containsKey(new ClassLoaderAndId(id)); + return store.containsKey(getClassLoader()) || storeById.containsKey(id); } @Override public void set(String id, T object) { store.put(getClassLoader(), object); - storeById.put(new ClassLoaderAndId(id, getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader()), object); + storeById.put(id, new ValueAndClassLoaders<>(object, getDeploymentOrContextClassLoader(), + Thread.currentThread().getContextClassLoader())); } @Override public void clear(String id) { store.remove(getClassLoader()); - storeById.remove(new ClassLoaderAndId(id, getDeploymentOrContextClassLoader(), Thread.currentThread().getContextClassLoader())); + storeById.get(id).removeIf(v -> + Objects.equals(v.classLoader, getDeploymentOrContextClassLoader()) + || Objects.equals(v.classLoader, Thread.currentThread().getContextClassLoader())); } } } From 6bebd5dcc3d774a903f08608614669c6ef1a6908 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 5 May 2025 10:49:24 -0500 Subject: [PATCH 31/32] cleanup: removed code and associated `fish.payara.war-beans-visible-in-ear-libs` system proeprty that's no longer necessary --- .../org/glassfish/weld/DeploymentImpl.java | 18 ------------------ .../java/org/glassfish/weld/WeldDeployer.java | 1 - 2 files changed, 19 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java index 9837548f345..f4282f3a316 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java @@ -46,7 +46,6 @@ import static java.util.logging.Level.WARNING; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; -import static org.glassfish.weld.WeldDeployer.MAKE_WARS_VISIBLE_IN_EAR_LIBS; import static org.glassfish.weld.connector.WeldUtils.*; import java.io.ByteArrayInputStream; @@ -400,23 +399,6 @@ public void buildDeploymentGraph() { warModuleBda.getBeanDeploymentArchives().add(libJarRootBda); warModuleBda.getBeanDeploymentArchives().add(libJarModuleBda); - // make WAR's BDAs accessible to libJar BDAs - boolean makeWarBDAsAccessibleToEARLibs = Boolean.parseBoolean(context.getAppProps() - .getProperty(MAKE_WARS_VISIBLE_IN_EAR_LIBS)) || Boolean.getBoolean(MAKE_WARS_VISIBLE_IN_EAR_LIBS); - if (makeWarBDAsAccessibleToEARLibs) { - Set seen = Collections.newSetFromMap(new IdentityHashMap<>()); - beanDeploymentArchives.stream() - .filter(RootBeanDeploymentArchive.class::isInstance) - .map(RootBeanDeploymentArchive.class::cast) - .forEach(bda -> - recursivelyAdd(bda.getBeanDeploymentArchives(), warModuleBda, seen, ejbModuleAndRarBDAs)); - recursivelyAdd(beanDeploymentArchives, warModuleBda, seen, ejbModuleAndRarBDAs); - libJarRootBda.getBeanDeploymentArchives().add(warRootBda); - libJarModuleBda.getBeanDeploymentArchives().add(warRootBda); - libJarRootBda.getBeanDeploymentArchives().add(warModuleBda); - libJarModuleBda.getBeanDeploymentArchives().add(warModuleBda); - } - for ( BeanDeploymentArchive oneBda : warModuleBda.getBeanDeploymentArchives() ) { oneBda.getBeanDeploymentArchives().add( libJarRootBda ); oneBda.getBeanDeploymentArchives().add( libJarModuleBda ); diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java index 1c1b7a2edef..2bae45ddd6a 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/WeldDeployer.java @@ -192,7 +192,6 @@ public class WeldDeployer extends SimpleDeployer Date: Mon, 5 May 2025 10:59:14 -0500 Subject: [PATCH 32/32] cleanup: remove unused `recursivelyAdd()` method --- .../main/java/org/glassfish/weld/DeploymentImpl.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java index f4282f3a316..298c566cfe8 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java @@ -454,16 +454,6 @@ private void addDependentBdas() { } } - private void recursivelyAdd(Collection bdas, BeanDeploymentArchive bda, Set seen, - Set excluded) { - for (BeanDeploymentArchive subBda : new LinkedHashSet<>(bdas)) { - if (seen.add(subBda) && !excluded.contains(subBda)) { - subBda.getBeanDeploymentArchives().add(bda); - recursivelyAdd(subBda.getBeanDeploymentArchives(), bda, seen, excluded); - } - } - } - @Override public Set getBeanDeploymentArchives() { if ( logger.isLoggable( FINE ) ) {