diff --git a/appserver/deployment/javaee-full/src/main/java/org/glassfish/javaee/full/deployment/EarDeployer.java b/appserver/deployment/javaee-full/src/main/java/org/glassfish/javaee/full/deployment/EarDeployer.java index ac8567bdd46..66f93f89b78 100644 --- a/appserver/deployment/javaee-full/src/main/java/org/glassfish/javaee/full/deployment/EarDeployer.java +++ b/appserver/deployment/javaee-full/src/main/java/org/glassfish/javaee/full/deployment/EarDeployer.java @@ -37,6 +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] package org.glassfish.javaee.full.deployment; @@ -101,7 +102,7 @@ @Service @PerLookup public class EarDeployer implements Deployer { - + public static final String PER_BDA_METADATA_KEY = "[PerBDA]"; // private static final Class GLASSFISH_APPCLIENT_GROUP_FACADE_CLASS = // org.glassfish.appclient.client.AppClientGroupFacade.class; // Currently using a string instead of a Class constant to avoid a circular @@ -457,15 +458,21 @@ public U getCommandParameters(Class commandParametersTy @Override public void addTransientAppMetaData(String metaDataKey, Object metaData) { - context.addTransientAppMetaData(metaDataKey, - metaData); + if (metaDataKey.startsWith(PER_BDA_METADATA_KEY)) { + super.addTransientAppMetaData(metaDataKey, metaData); + } else { + context.addTransientAppMetaData(metaDataKey, metaData); + } } @Override public T getTransientAppMetaData(String metaDataKey, Class metadataType) { - return context.getTransientAppMetaData(metaDataKey, - metadataType); + if (metaDataKey.startsWith(PER_BDA_METADATA_KEY)) { + return super.getTransientAppMetaData(metaDataKey, metadataType); + } else { + return context.getTransientAppMetaData(metaDataKey, metadataType); + } } @Override 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 184a492b006..79f89f969a9 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-2019] Payara Foundation and/or affiliates + * Portions Copyright [2017-2024] Payara Foundation and/or affiliates */ package org.glassfish.weld; @@ -108,11 +108,11 @@ public ClassLoader run() @Override public T get( String id ) { - ClassLoader acl = getClassLoader(); - T instance = store.get(acl); + T instance = storeById.get(id); if (instance == null) { - instance = storeById.get(id); + ClassLoader acl = getClassLoader(); + instance = store.get(acl); if (instance == null) { throw new IllegalStateException("Singleton not set for " + acl); } diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanDeploymentArchiveImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanDeploymentArchiveImpl.java index b61dcc8a2b9..fceeffbf7d9 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanDeploymentArchiveImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanDeploymentArchiveImpl.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2022] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2024] [Payara Foundation and/or its affiliates] package org.glassfish.weld; @@ -64,7 +64,6 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.*; @@ -102,9 +101,8 @@ public class BeanDeploymentArchiveImpl implements BeanDeploymentArchive { private BDAType bdaType = BDAType.UNKNOWN; - private DeploymentContext context; - - private WeldBootstrap weldBootstrap; + DeploymentContext context; + WeldBootstrap weldBootstrap; private final Map, InjectionTarget> itMap = new HashMap<>(); @@ -272,7 +270,7 @@ public BeansXml getBeansXml() { if (beansXmlURLs.size() == 1) { result = weldBootstrap.parse(beansXmlURLs.get(0)); } else { - // This method attempts to performs a merge, but loses some + // This method attempts to perform a merge, but loses some // information (e.g., version, bean-discovery-mode) result = weldBootstrap.parse(beansXmlURLs); } diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanManagerNamingProxy.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanManagerNamingProxy.java index b9974012c6d..f156f38e081 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanManagerNamingProxy.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/BeanManagerNamingProxy.java @@ -37,6 +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] package org.glassfish.weld; @@ -93,7 +94,9 @@ public Object handle(String name) throws NamingException { if( inv != null ) { - JndiNameEnvironment componentEnv = compEnvManager.getJndiNameEnvironment(inv.getComponentId()); + JndiNameEnvironment componentEnv = inv.getComponentId() != null + ? compEnvManager.getJndiNameEnvironment(inv.getComponentId()) + : null; if( componentEnv != null ) { @@ -112,7 +115,7 @@ public Object handle(String name) throws NamingException { if( bundle != null ) { BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(bundle); if( bda != null ) { - WeldBootstrap bootstrap = weldDeployer.getBootstrapForApp(bundle.getApplication()); + WeldBootstrap bootstrap = weldDeployer.getBootstrapForArchive(bda); //System.out.println("BeanManagerNamingProxy:: getting BeanManagerImpl for" + bda); beanManager = bootstrap.getManager(bda); } @@ -122,7 +125,6 @@ public Object handle(String name) throws NamingException { throw new IllegalStateException("Cannot resolve bean manager"); } - } else { throw new IllegalStateException("No invocation context found"); } @@ -137,6 +139,4 @@ public Object handle(String name) throws NamingException { return beanManager; } - - } 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 caaae19ab44..b6ea7827b11 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 @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2022] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2024] [Payara Foundation and/or its affiliates] package org.glassfish.weld; @@ -97,12 +97,12 @@ public class DeploymentImpl implements CDI11Deployment { // Keep track of our BDAs for this deployment private List rarRootBdas; - private List ejbRootBdas; + List ejbRootBdas; private List warRootBdas; private List libJarRootBdas = null; private List beanDeploymentArchives = new ArrayList<>(); - private DeploymentContext context; + DeploymentContext context; // A convenience Map to get BDA for a given BDA ID private Map idToBeanDeploymentArchive = new HashMap<>(); @@ -164,24 +164,80 @@ public DeploymentImpl(ReadableArchive archive, createModuleBda(archive, ejbs, context, contextId); } + private DeploymentImpl(InjectionManager injectionManager) { + this.injectionManager = injectionManager; + } + + DeploymentImpl filter(RootBeanDeploymentArchive rootBDA) { + DeploymentImpl filteredDeployment = new DeploymentImpl(injectionManager); + + List nonRooIDs = List.of(rootBDA.getId(), rootBDA.getModuleBda().getId()); + + filteredDeployment.rarRootBdas = filterBDAs(rarRootBdas, nonRooIDs); + filteredDeployment.ejbRootBdas = filterBDAs(ejbRootBdas, nonRooIDs); + filteredDeployment.warRootBdas = filterBDAs(warRootBdas, nonRooIDs); + filteredDeployment.libJarRootBdas = filterBDAs(libJarRootBdas, nonRooIDs); + filteredDeployment.beanDeploymentArchives = filterBDAs(beanDeploymentArchives, nonRooIDs); + filteredDeployment.extensions = extensions; + filteredDeployment.dynamicExtensions = dynamicExtensions; + filteredDeployment.deployedEjbs = deployedEjbs; + filteredDeployment.archiveFactory = archiveFactory; + filteredDeployment.context = rootBDA.context; + filteredDeployment.appName = appName; + filteredDeployment.contextId = rootBDA.getId() + ".bda"; + filteredDeployment.earContextAppLibBdasProcessed = earContextAppLibBdasProcessed; + filteredDeployment.idToBeanDeploymentArchive = idToBeanDeploymentArchive; + filteredDeployment.simpleServiceRegistry = simpleServiceRegistry; + + return filteredDeployment; + } + + List getRootBDAs() { + if (warRootBdas != null) { + return warRootBdas; + } else if (ejbRootBdas != null) { + return ejbRootBdas; + } else if (rarRootBdas != null) { + return rarRootBdas; + } else if (libJarRootBdas != null) { + return libJarRootBdas; + } else { + return Collections.emptyList(); + } + } + + private List filterBDAs(List bdas, List bda) { + if (bdas == null) { + return null; + } + return bdas.stream() + .filter(b -> bda.stream().anyMatch(b.getId()::startsWith)) + .collect(toList()); + } + private void addBeanDeploymentArchives(RootBeanDeploymentArchive bda) { + rootBDAs(bda).add(bda); + } + + private List rootBDAs(RootBeanDeploymentArchive bda) { BDAType moduleBDAType = bda.getModuleBDAType(); if (moduleBDAType.equals(BDAType.WAR)) { if (warRootBdas == null) { warRootBdas = new ArrayList<>(); } - warRootBdas.add(bda); + return warRootBdas; } else if (moduleBDAType.equals(BDAType.JAR)) { if (ejbRootBdas == null) { ejbRootBdas = new ArrayList<>(); } - ejbRootBdas.add(bda); + return ejbRootBdas; } else if (moduleBDAType.equals(BDAType.RAR)) { if (rarRootBdas == null) { rarRootBdas = new ArrayList<>(); } - rarRootBdas.add(bda); + return rarRootBdas; } + throw new IllegalArgumentException("Unknown BDAType: " + moduleBDAType); } /** @@ -765,9 +821,9 @@ public BeanDeploymentArchive getBeanDeploymentArchive(Class beanClass) { return null; } - for ( BeanDeploymentArchive oneBda : beanDeploymentArchives ) { + for (BeanDeploymentArchive oneBda : beanDeploymentArchives) { BeanDeploymentArchiveImpl beanDeploymentArchiveImpl = (BeanDeploymentArchiveImpl) oneBda; - if ( beanDeploymentArchiveImpl.getKnownClasses().contains(beanClass.getName()) ) { + if (beanDeploymentArchiveImpl.getKnownClasses().contains(beanClass.getName())) { return oneBda; } } 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 0d7d7282572..94ffbb866da 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,9 +37,15 @@ * only if the new code is made subject to such option by the copyright * holder. */ +// Portions Copyright [2024] [Payara Foundation and/or its affiliates] package org.glassfish.weld; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.EjbDescriptor; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import org.glassfish.api.invocation.InvocationManager; +import org.glassfish.internal.api.Globals; import org.jboss.weld.Container; import org.jboss.weld.SimpleCDI; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; @@ -54,7 +60,16 @@ * @author JJ Snyder */ 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 class GlassFishEnhancedWeld extends SimpleCDI { + GlassFishEnhancedWeld() { + } + + GlassFishEnhancedWeld(String contextId) { + super(contextId == null ? Container.instance() : Container.instance(contextId)); + } @Override protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { @@ -92,15 +107,30 @@ protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { @Override public CDI getCDI() { - try { - return new GlassFishEnhancedWeld(); - } catch ( Throwable throwable ) { - Throwable cause = throwable.getCause(); - if ( cause instanceof IllegalStateException ) { - return null; + 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); + if (bda == null) { + return new GlassFishEnhancedWeld(); + } else { + return new GlassFishEnhancedWeld(weldDeployer.getContextIdForArchive(bda)); + } + } catch ( Throwable throwable ) { + Throwable cause = throwable.getCause(); + if ( cause instanceof IllegalStateException ) { + return null; + } + throw throwable; } - throw throwable; - } } - } diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ValidationNamingProxy.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ValidationNamingProxy.java index 1e4f1e1780c..345ddfe2950 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ValidationNamingProxy.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ValidationNamingProxy.java @@ -37,6 +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] package org.glassfish.weld; @@ -48,7 +49,6 @@ import org.glassfish.api.invocation.ComponentInvocation; import org.glassfish.api.invocation.InvocationManager; import org.glassfish.api.naming.NamedNamingObjectProxy; -import org.glassfish.api.naming.NamespacePrefixes; import org.glassfish.hk2.api.ServiceLocator; import org.jboss.weld.bootstrap.WeldBootstrap; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; @@ -59,9 +59,7 @@ import jakarta.inject.Inject; import jakarta.inject.Named; import javax.naming.NamingException; -import jakarta.validation.Validation; import jakarta.validation.Validator; -import jakarta.validation.ValidatorContext; import jakarta.validation.ValidatorFactory; import java.util.Set; @@ -189,7 +187,7 @@ private synchronized BeanManager obtainBeanManager() throws NamingException { if( bundle != null ) { BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(bundle); if( bda != null ) { - WeldBootstrap bootstrap = weldDeployer.getBootstrapForApp(bundle.getApplication()); + WeldBootstrap bootstrap = weldDeployer.getBootstrapForArchive(bda); beanManager = bootstrap.getManager(bda); } 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 cfb0a6c9c14..cdaf362f840 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 @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2022] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2024] [Payara Foundation and/or its affiliates] package org.glassfish.weld; @@ -67,6 +67,7 @@ import static org.jboss.weld.manager.BeanManagerLookupService.lookupBeanManager; import java.security.AccessController; +import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; @@ -124,7 +125,6 @@ import org.jboss.weld.ejb.spi.EjbServices; import org.jboss.weld.exceptions.WeldException; import org.jboss.weld.injection.spi.InjectionServices; -import org.jboss.weld.injection.spi.ResourceInjectionServices; import org.jboss.weld.probe.ProbeExtension; import org.jboss.weld.resources.spi.ResourceLoader; import org.jboss.weld.security.NewInstanceAction; @@ -156,7 +156,7 @@ public class WeldDeployer extends SimpleDeployer appToBootstrap = new HashMap<>(); - private Map bundleToBeanDeploymentArchive = new HashMap<>(); private static final Class[] NON_CONTEXT_CLASSES = { @@ -277,11 +275,7 @@ public WeldApplicationContainer load(WeldContainer container, DeploymentContext ReadableArchive archive = context.getSource(); - boolean[] setTransientAppMetaData = {false}; - - // See if a WeldBootsrap has already been created - only want one per app. - WeldBootstrap bootstrap = getWeldBootstrap(context, applicationInfo, setTransientAppMetaData); - + ensureWeldBootstrapCreated(context, applicationInfo); EjbBundleDescriptor ejbBundle = getEjbBundleFromContext(context); EjbServices ejbServices = null; @@ -296,7 +290,7 @@ public WeldApplicationContainer load(WeldContainer container, DeploymentContext // If the archive is a composite, or has version numbers per maven conventions, strip them out String archiveName = getArchiveName(context, applicationInfo, archive); - DeploymentImpl deploymentImpl = context.getTransientAppMetaData(WELD_DEPLOYMENT, DeploymentImpl.class); + DeploymentImpl deploymentImpl = applicationInfo.getTransientAppMetaData(WELD_DEPLOYMENT, DeploymentImpl.class); if (deploymentImpl == null) { deploymentImpl = new DeploymentImpl(archive, ejbs, context, archiveFactory, archiveName, services.getService(InjectionManager.class)); @@ -338,12 +332,6 @@ public WeldApplicationContainer load(WeldContainer container, DeploymentContext BeanDeploymentArchive beanDeploymentArchive = deploymentImpl.getBeanDeploymentArchiveForArchive(archiveName); if (beanDeploymentArchive != null && !beanDeploymentArchive.getBeansXml().getBeanDiscoveryMode().equals(NONE)) { - if (setTransientAppMetaData[0]) { - // Do this only if we have a root BDA - appToBootstrap.put(context.getModuleMetaData(Application.class), bootstrap); - applicationInfo.addTransientAppMetaData(WELD_BOOTSTRAP, bootstrap); - } - WebBundleDescriptor webBundleDescriptor = context.getModuleMetaData(WebBundleDescriptor.class); boolean developmentMode = isDevelopmentMode(context); if (webBundleDescriptor != null) { @@ -417,7 +405,6 @@ public WeldApplicationContainer load(WeldContainer container, DeploymentContext } } - context.addTransientAppMetaData(WELD_DEPLOYMENT, deploymentImpl); applicationInfo.addTransientAppMetaData(WELD_DEPLOYMENT, deploymentImpl); return new WeldApplicationContainer(); @@ -467,139 +454,176 @@ public boolean is299Enabled(BundleDescriptor bundle) { return bundleToBeanDeploymentArchive.containsKey(bundle); } - public WeldBootstrap getBootstrapForApp(Application app) { - return appToBootstrap.get(app); + public WeldBootstrap getBootstrapForArchive(BeanDeploymentArchive archive) { + return ((BeanDeploymentArchiveImpl) archive).weldBootstrap; } - + public String getContextIdForArchive(BeanDeploymentArchive archive) { + var impl = (BeanDeploymentArchiveImpl) archive; + String rootContextId = impl.getBeanDeploymentArchives().stream() + .filter(RootBeanDeploymentArchive.class::isInstance) + .findFirst().map(BeanDeploymentArchive::getId).orElse(null); + return rootContextId == null ? null : rootContextId + ".bda"; + } // ### Private methods + private WeldBootstrap ensureWeldBootstrapCreated(DeploymentContext context, ApplicationInfo applicationInfo) { + @SuppressWarnings("unchecked") + List toShutdown = applicationInfo.getTransientAppMetaData(WELD_BOOTSTRAP, List.class); + if (toShutdown == null) { + toShutdown = new ArrayList<>(); + applicationInfo.addTransientAppMetaData(WELD_BOOTSTRAP, toShutdown); + } - private WeldBootstrap getWeldBootstrap(DeploymentContext context, ApplicationInfo appInfo, boolean[] setTransientAppMetaData) { - // See if a WeldBootsrap has already been created - only want one per app. + // See if a WeldBootstrap has already been created - only want one per context. WeldBootstrap bootstrap = context.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class); - if (bootstrap != null && appInfo.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class) == null) { - // No bootstrap if no CDI BDAs exist yet - bootstrap = null; - } - if (bootstrap == null) { bootstrap = new WeldBootstrap(); - setTransientAppMetaData[0] = true; - // Stash the WeldBootstrap instance, so we may access the WeldManager later.. + // Stash the WeldBootstrap instance, so we may access the WeldManager later... context.addTransientAppMetaData(WELD_BOOTSTRAP, bootstrap); + toShutdown.add(bootstrap); // Making sure that if WeldBootstrap is added, shutdown is set to false, as it is/would not have // been called. - appInfo.addTransientAppMetaData(WELD_BOOTSTRAP_SHUTDOWN, "false"); + applicationInfo.addTransientAppMetaData(WELD_BOOTSTRAP_SHUTDOWN, "false"); } - return bootstrap; } private void processApplicationLoaded(ApplicationInfo applicationInfo) { - WeldBootstrap bootstrap = applicationInfo.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class); + DeploymentImpl deploymentImpl = applicationInfo.getTransientAppMetaData(WELD_DEPLOYMENT, DeploymentImpl.class); + if (deploymentImpl == null) { + return; + } + deploymentImpl.buildDeploymentGraph(); - if (bootstrap != null) { - DeploymentImpl deploymentImpl = applicationInfo.getTransientAppMetaData(WELD_DEPLOYMENT, DeploymentImpl.class); - deploymentImpl.buildDeploymentGraph(); + List archives = deploymentImpl.getBeanDeploymentArchives(); - List archives = deploymentImpl.getBeanDeploymentArchives(); + addResourceLoaders(archives); + addCdiServicesToNonModuleBdas(deploymentImpl.getLibJarRootBdas(), services.getService(InjectionManager.class)); + addCdiServicesToNonModuleBdas(deploymentImpl.getRarRootBdas(), services.getService(InjectionManager.class)); - addResourceLoaders(archives); - addCdiServicesToNonModuleBdas(deploymentImpl.getLibJarRootBdas(), services.getService(InjectionManager.class)); - addCdiServicesToNonModuleBdas(deploymentImpl.getRarRootBdas(), services.getService(InjectionManager.class)); + // Get current TCL + ClassLoader oldTCL = Thread.currentThread().getContextClassLoader(); - // Get current TCL - ClassLoader oldTCL = Thread.currentThread().getContextClassLoader(); + invocationManager.pushAppEnvironment(applicationInfo::getName); - invocationManager.pushAppEnvironment(applicationInfo::getName); + ComponentInvocation componentInvocation = createComponentInvocation(applicationInfo); - ComponentInvocation componentInvocation = createComponentInvocation(applicationInfo); + try { + invocationManager.preInvoke(componentInvocation); + // Modern, multiple WARs in an EAR scenario + if (deploymentImpl.ejbRootBdas == null || deploymentImpl.ejbRootBdas.isEmpty()) { + for (RootBeanDeploymentArchive rootBDA : deploymentImpl.getRootBDAs()) { + DeploymentImpl filtered = deploymentImpl.filter(rootBDA); + WeldBootstrap bootstrap = filtered.context.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class); + startWeldBootstrap(applicationInfo, rootBDA, bootstrap, filtered, componentInvocation); + } + } else if (!deploymentImpl.getRootBDAs().isEmpty()) { + // Legacy EJB-Jar scenario, one Weld instance per EAR + RootBeanDeploymentArchive bda = deploymentImpl.getRootBDAs().get(0); + WeldBootstrap bootstrap = unifyBootstrap(bda, applicationInfo); + startWeldBootstrap(applicationInfo, bda, bootstrap, deploymentImpl, componentInvocation); + } + } catch (Throwable t) { + doBootstrapShutdown(applicationInfo); + throw new DeploymentException(getDeploymentErrorMsgPrefix(t) + t.getMessage(), t); + } finally { try { - invocationManager.preInvoke(componentInvocation); - bootstrap.startExtensions(postProcessExtensions(deploymentImpl.getExtensions(), archives)); - bootstrap.startContainer(deploymentImpl.getContextId() + ".bda", SERVLET, deploymentImpl); - - //This changes added to pass the following test - // CreateBeanAttributesTest#testBeanAttributesForSessionBean - if(!deploymentImpl.getBeanDeploymentArchives().isEmpty()) { - BeanDeploymentArchive rootArchive = deploymentImpl.getBeanDeploymentArchives().get(0); - ServiceRegistry rootServices = bootstrap.getManager(rootArchive).getServices(); - EjbSupport originalEjbSupport = rootServices.get(EjbSupport.class); - if (originalEjbSupport != null) { - // We need to create a proxy instead of a simple wrapper - EjbSupport proxyEjbSupport = (EjbSupport) java.lang.reflect.Proxy.newProxyInstance(EjbSupport.class.getClassLoader(), - new Class[]{EjbSupport.class}, new java.lang.reflect.InvocationHandler() { - @Override - public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable { - if (method.getName().equals("isEjb")) { - - EjbSupport targetEjbSupport = getTargetEjbSupport((Class) args[0]); - - if (targetEjbSupport != null) { - return method.invoke(targetEjbSupport, args); - } - - } else if (method.getName().equals("createSessionBeanAttributes")) { - Object enhancedAnnotated = args[0]; - - Class beanClass = (Class) - enhancedAnnotated.getClass() - .getMethod("getJavaClass") - .invoke(enhancedAnnotated); - - EjbSupport targetEjbSupport = getTargetEjbSupport(beanClass); - if (targetEjbSupport != null) { - return method.invoke(targetEjbSupport, args); - } - } - - return method.invoke(originalEjbSupport, args); - } - - private EjbSupport getTargetEjbSupport(Class beanClass) { - BeanDeploymentArchive ejbArchive = deploymentImpl.getBeanDeploymentArchive(beanClass); - if (ejbArchive == null) { - return null; - } - - BeanManagerImpl ejbBeanManager = lookupBeanManager(beanClass, bootstrap.getManager(ejbArchive)); - - return ejbBeanManager.getServices().get(EjbSupport.class); - } - }); - rootServices.add(EjbSupport.class, proxyEjbSupport); - } - } - bootstrap.startInitialization(); - fireProcessInjectionTargetEvents(bootstrap, applicationInfo, deploymentImpl); - bootstrap.deployBeans(); - bootstrap.validateBeans(); - bootstrap.endInitialization(); + invocationManager.postInvoke(componentInvocation); + invocationManager.popAppEnvironment(); + deploymentComplete(deploymentImpl); } catch (Throwable t) { - doBootstrapShutdown(applicationInfo); + logger.log(SEVERE, "Exception dispatching post deploy event", t); + } - throw new DeploymentException(getDeploymentErrorMsgPrefix(t) + t.getMessage(), t); - } finally { - try { - invocationManager.postInvoke(componentInvocation); - invocationManager.popAppEnvironment(); - deploymentComplete(deploymentImpl); - } catch (Throwable t) { - logger.log(SEVERE, "Exception dispatching post deploy event", t); - } + // The TCL is originally the EAR classloader and is reset during Bean deployment to the + // corresponding module classloader in BeanDeploymentArchiveImpl.getBeans + // for Bean classloading to succeed. + // The TCL is reset to its old value here. + Thread.currentThread().setContextClassLoader(oldTCL); + } + } - // The TCL is originally the EAR classloader and is reset during Bean deployment to the - // corresponding module classloader in BeanDeploymentArchiveImpl.getBeans - // for Bean classloading to succeed. - // The TCL is reset to its old value here. - Thread.currentThread().setContextClassLoader(oldTCL); - } + private WeldBootstrap unifyBootstrap(BeanDeploymentArchiveImpl rootArchive, ApplicationInfo applicationInfo) { + WeldBootstrap bootstrap = ensureWeldBootstrapCreated(rootArchive.context, applicationInfo); + rootArchive.getBeanDeploymentArchives().stream().map(BeanDeploymentArchiveImpl.class::cast) + .forEach(bda -> bda.weldBootstrap = bootstrap); + return bootstrap; + } + + private void startWeldBootstrap(ApplicationInfo applicationInfo, RootBeanDeploymentArchive rootBDA, + WeldBootstrap bootstrap, DeploymentImpl deploymentImpl, + ComponentInvocation componentInvocation) { + bootstrap.startExtensions(postProcessExtensions(deploymentImpl.getExtensions(), + deploymentImpl.getBeanDeploymentArchives())); + bootstrap.startContainer(deploymentImpl.getContextId(), SERVLET, deploymentImpl); + + //This changes added to pass the following test + // CreateBeanAttributesTest#testBeanAttributesForSessionBean + if (!rootBDA.getBeanDeploymentArchives().isEmpty()) { + createProxyEJBs(rootBDA, bootstrap, componentInvocation, deploymentImpl); + } + bootstrap.startInitialization(); + fireProcessInjectionTargetEvents(bootstrap, applicationInfo, deploymentImpl); + bootstrap.deployBeans(); + bootstrap.validateBeans(); + bootstrap.endInitialization(); + } + + private static void createProxyEJBs(RootBeanDeploymentArchive warRootBDA, WeldBootstrap bootstrap, + ComponentInvocation componentInvocation, DeploymentImpl deploymentImpl) { + BeanManagerImpl beanManager = bootstrap.getManager(warRootBDA); + componentInvocation.setInstance(beanManager); + ServiceRegistry rootServices = beanManager.getServices(); + EjbSupport originalEjbSupport = rootServices.get(EjbSupport.class); + if (originalEjbSupport != null) { + // We need to create a proxy instead of a simple wrapper + EjbSupport proxyEjbSupport = (EjbSupport) java.lang.reflect.Proxy.newProxyInstance(EjbSupport.class.getClassLoader(), + new Class[]{EjbSupport.class}, new java.lang.reflect.InvocationHandler() { + @Override + public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable { + if (method.getName().equals("isEjb")) { + + EjbSupport targetEjbSupport = getTargetEjbSupport((Class) args[0]); + + if (targetEjbSupport != null) { + return method.invoke(targetEjbSupport, args); + } + + } else if (method.getName().equals("createSessionBeanAttributes")) { + Object enhancedAnnotated = args[0]; + + Class beanClass = (Class) + enhancedAnnotated.getClass() + .getMethod("getJavaClass") + .invoke(enhancedAnnotated); + + EjbSupport targetEjbSupport = getTargetEjbSupport(beanClass); + if (targetEjbSupport != null) { + return method.invoke(targetEjbSupport, args); + } + } + + return method.invoke(originalEjbSupport, args); + } + + private EjbSupport getTargetEjbSupport(Class beanClass) { + BeanDeploymentArchive ejbArchive = deploymentImpl.getBeanDeploymentArchive(beanClass); + if (ejbArchive == null) { + return null; + } + + BeanManagerImpl ejbBeanManager = lookupBeanManager(beanClass, bootstrap.getManager(ejbArchive)); + + return ejbBeanManager.getServices().get(EjbSupport.class); + } + }); + rootServices.add(EjbSupport.class, proxyEjbSupport); } } @@ -608,7 +632,6 @@ private void processApplicationStopped(ApplicationInfo applicationInfo) { Application application = applicationInfo.getMetaData(Application.class); if (application != null) { removeBundleDescriptors(application); - appToBootstrap.remove(application); } String shutdown = applicationInfo.getTransientAppMetaData(WELD_SHUTDOWN, String.class); @@ -620,8 +643,6 @@ private void processApplicationStopped(ApplicationInfo applicationInfo) { Thread.currentThread().setContextClassLoader(applicationInfo.getAppClassLoader()); try { - WeldBootstrap bootstrap = applicationInfo.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class); - if (bootstrap != null) { invocationManager.pushAppEnvironment(applicationInfo::getName); try { @@ -633,7 +654,6 @@ private void processApplicationStopped(ApplicationInfo applicationInfo) { } applicationInfo.addTransientAppMetaData(WELD_SHUTDOWN, "true"); - } } finally { Thread.currentThread().setContextClassLoader(currentContextClassLoader); } @@ -759,11 +779,13 @@ private void deploymentComplete(DeploymentImpl deploymentImpl) { } private void doBootstrapShutdown(ApplicationInfo applicationInfo) { - WeldBootstrap bootstrap = applicationInfo.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class); + List bootstrap = applicationInfo.getTransientAppMetaData(WELD_BOOTSTRAP, List.class); String bootstrapShutdown = applicationInfo.getTransientAppMetaData(WELD_BOOTSTRAP_SHUTDOWN, String.class); if (bootstrapShutdown == null || Boolean.valueOf(bootstrapShutdown).equals(FALSE)) { - bootstrap.shutdown(); + if (bootstrap != null) { + bootstrap.forEach(WeldBootstrap::shutdown); + } applicationInfo.addTransientAppMetaData(WELD_BOOTSTRAP_SHUTDOWN, "true"); } } diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/JCDIServiceImpl.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/JCDIServiceImpl.java index a29bf9be94e..1447d3de0a1 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/JCDIServiceImpl.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/services/JCDIServiceImpl.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2022] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2024] [Payara Foundation and/or its affiliates] package org.glassfish.weld.services; @@ -213,7 +213,7 @@ private JCDIInjectionContext _createJCDIInjectionContext(EjbDescriptor ej // First get BeanDeploymentArchive for this ejb BeanDeploymentArchive bda = getBDAForBeanClass(topLevelBundleDesc, ejb.getEjbClassName()); - WeldBootstrap bootstrap = weldDeployer.getBootstrapForApp(ejb.getEjbBundleDescriptor().getApplication()); + WeldBootstrap bootstrap = weldDeployer.getBootstrapForArchive(bda); WeldManager weldManager = bootstrap.getManager(bda); //sanitizing the null reference of weldManager and returning null //when calling _createJCDIInjectionContext @@ -350,9 +350,8 @@ public void injectManagedObject(T managedObject, BundleDescriptor bundle) { BundleDescriptor topLevelBundleDesc = (BundleDescriptor) bundle.getModuleDescriptor().getDescriptor(); // First get BeanDeploymentArchive for this ejb - BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(topLevelBundleDesc); - //BeanDeploymentArchive bda = getBDAForBeanClass(topLevelBundleDesc, managedObject.getClass().getName()); - WeldBootstrap bootstrap = weldDeployer.getBootstrapForApp(bundle.getApplication()); + BeanDeploymentArchive bda = getBDAForBeanClass(topLevelBundleDesc, managedObject.getClass().getName()); + WeldBootstrap bootstrap = weldDeployer.getBootstrapForArchive(bda); BeanManager beanManager = bootstrap.getManager(bda); @SuppressWarnings("unchecked") AnnotatedType annotatedType = beanManager.createAnnotatedType((Class) managedObject.getClass()); @@ -400,7 +399,7 @@ public T createInterceptorInstance(Class interceptorClass, // First get BeanDeploymentArchive for this ejb BeanDeploymentArchive bda = getBDAForBeanClass(topLevelBundleDesc, ejb.getEjbClassName()); - WeldBootstrap bootstrap = weldDeployer.getBootstrapForApp(ejb.getEjbBundleDescriptor().getApplication()); + WeldBootstrap bootstrap = weldDeployer.getBootstrapForArchive(bda); BeanManagerImpl beanManager = bootstrap.getManager(bda); org.jboss.weld.ejb.spi.EjbDescriptor ejbDesc = beanManager.getEjbDescriptor( ejb.getName()); @@ -481,7 +480,7 @@ public JCDIInjectionContext createManagedObject(Class managedClass, Bu // First get BeanDeploymentArchive for this ejb BeanDeploymentArchive bda = weldDeployer.getBeanDeploymentArchiveForBundle(topLevelBundleDesc); - WeldBootstrap bootstrap = weldDeployer.getBootstrapForApp(bundle.getApplication()); + WeldBootstrap bootstrap = weldDeployer.getBootstrapForArchive(bda); BeanManager beanManager = bootstrap.getManager(bda); diff --git a/appserver/web/weld-integration/src/test/java/org/glassfish/weld/services/JCDIServiceImplTest.java b/appserver/web/weld-integration/src/test/java/org/glassfish/weld/services/JCDIServiceImplTest.java index b0600055c20..d63a137c465 100644 --- a/appserver/web/weld-integration/src/test/java/org/glassfish/weld/services/JCDIServiceImplTest.java +++ b/appserver/web/weld-integration/src/test/java/org/glassfish/weld/services/JCDIServiceImplTest.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2021] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2021-2024] 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 @@ -96,26 +96,24 @@ public void createJCDIInjectionContextWithoutNullPointerException() { Collection emptyListNames = Collections.emptyList(); Collection emptyListOfArchives = Collections.emptyList(); when(ejbDescriptor.getEjbBundleDescriptor()).thenReturn(ejbBundleDescriptor); - when(ejbBundleDescriptor.getApplication()).thenReturn(application); when(ejbBundleDescriptor.getModuleDescriptor()).thenReturn(moduleDescriptor); when(moduleDescriptor.getDescriptor()).thenReturn(bundleDescriptor); when(ejbDescriptor.getEjbClassName()).thenReturn("EjbName"); when(weldDeployer.getBeanDeploymentArchiveForBundle(bundleDescriptor)).thenReturn(beanDeploymentArchive); - when(weldDeployer.getBootstrapForApp(application)).thenReturn(bootstrap); + when(weldDeployer.getBootstrapForArchive(beanDeploymentArchive)).thenReturn(bootstrap); when(beanDeploymentArchive.getBeanClasses()).thenReturn(emptyListNames); when(beanDeploymentArchive.getBeanDeploymentArchives()).thenReturn(emptyListOfArchives); Object obj = jcdiServiceImpl.createJCDIInjectionContext(ejbDescriptor, ejbInfo); assertNull(obj); - verify(ejbDescriptor, times(2)).getEjbBundleDescriptor(); + verify(ejbDescriptor, times(1)).getEjbBundleDescriptor(); verify(ejbBundleDescriptor, times(1)).getModuleDescriptor(); verify(moduleDescriptor, times(1)).getDescriptor(); verify(weldDeployer, times(1)).getBeanDeploymentArchiveForBundle(bundleDescriptor); verify(beanDeploymentArchive, times(1)).getBeanClasses(); verify(beanDeploymentArchive, times(1)).getBeanDeploymentArchives(); - verify(ejbBundleDescriptor, times(1)).getApplication(); - verify(weldDeployer, times(1)).getBootstrapForApp(application); + verify(weldDeployer, times(1)).getBootstrapForArchive(beanDeploymentArchive); verify(bootstrap, times(1)).getManager(beanDeploymentArchive); } } \ No newline at end of file diff --git a/nucleus/common/common-util/src/main/java/com/sun/enterprise/loader/DirWatcher.java b/nucleus/common/common-util/src/main/java/com/sun/enterprise/loader/DirWatcher.java index d6599566f67..d060653b2dd 100644 --- a/nucleus/common/common-util/src/main/java/com/sun/enterprise/loader/DirWatcher.java +++ b/nucleus/common/common-util/src/main/java/com/sun/enterprise/loader/DirWatcher.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2019-2024] 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 @@ -208,7 +208,7 @@ protected void register() { try (Stream stream = Files.list(root)){ stream.forEach(this::registerSubProcessor); } catch (IOException e) { - LOGGER.log(Level.INFO, "Error when listing directory",e); + LOGGER.log(Level.FINE, "Error when listing directory",e); } }