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/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/ACLSingletonProvider.java b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/ACLSingletonProvider.java index 79f89f969a9..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,21 +37,28 @@ * 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; +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; 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 @@ -83,11 +90,39 @@ 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; + + public ValueAndClassLoaders(TT value, ClassLoader classLoader, ClassLoader backupClassLoader) { + this.value = value; + this.classLoader = classLoader; + this.backupClassLoader = 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); + } + + 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. // I think either android or IBM JVM does not use null for bootstap loader @@ -108,9 +143,11 @@ public ClassLoader run() @Override public T get( String id ) { - T instance = storeById.get(id); - if (instance == null) - { + T instance = findByClassLoader(storeById.get(id), getDeploymentOrContextClassLoader()); + if (instance == null) { + instance = findByIdOnly(storeById.get(id)); + } + if (instance == null) { ClassLoader acl = getClassLoader(); instance = store.get(acl); if (instance == null) { @@ -120,6 +157,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 @@ -196,13 +241,16 @@ public boolean isSet(String id) { @Override public void set(String id, T object) { store.put(getClassLoader(), object); - storeById.put(id, object); + storeById.put(id, new ValueAndClassLoaders<>(object, getDeploymentOrContextClassLoader(), + Thread.currentThread().getContextClassLoader())); } @Override public void clear(String id) { store.remove(getClassLoader()); - storeById.remove(id); + storeById.get(id).removeIf(v -> + Objects.equals(v.classLoader, getDeploymentOrContextClassLoader()) + || Objects.equals(v.classLoader, Thread.currentThread().getContextClassLoader())); } } } 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..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 @@ -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) { @@ -313,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) { @@ -345,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); @@ -391,18 +399,6 @@ public void buildDeploymentGraph() { warModuleBda.getBeanDeploymentArchives().add(libJarRootBda); 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)); - recursivelyAdd(beanDeploymentArchives, warModuleBda, seen); - 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 ); @@ -458,15 +454,6 @@ private void addDependentBdas() { } } - private void recursivelyAdd(Collection bdas, BeanDeploymentArchive bda, Set seen) { - for (BeanDeploymentArchive subBda : new LinkedHashSet<>(bdas)) { - if (seen.add(subBda)) { - subBda.getBeanDeploymentArchives().add(bda); - recursivelyAdd(subBda.getBeanDeploymentArchives(), bda, seen); - } - } - } - @Override public Set getBeanDeploymentArchives() { if ( logger.isLoggable( FINE ) ) { 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..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 @@ -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; @@ -49,12 +49,17 @@ 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.lang.StackWalker.StackFrame; +import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; /** * @author JJ Snyder @@ -62,13 +67,18 @@ 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; + GlassFishEnhancedWeld() { + knownClassNames = new HashSet<>(super.knownClassNames); } GlassFishEnhancedWeld(String contextId) { super(contextId == null ? Container.instance() : Container.instance(contextId)); + knownClassNames = new HashSet<>(super.knownClassNames); } @Override @@ -103,23 +113,40 @@ protected BeanManagerImpl unsatisfiedBeanManager(String callerClassName) { return super.unsatisfiedBeanManager(callerClassName); } + + @Override + protected String getCallingClassName() { + boolean outerSubclassReached = false; + 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())) { + 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; + } + } + 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 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 { @@ -133,4 +160,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; + } } 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..9bc502a038d --- /dev/null +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/weld/JaxRSJsonContextResolver.java @@ -0,0 +1,126 @@ +/* + * 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.inject.Inject; +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.inject.InjectionManager; +import org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable; +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; +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<>(); + 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, + List>> existingResolverClasses) { + this.existingResolvers = existingResolvers; + this.existingResolverClasses = existingResolverClasses; + } + + @Override + public void configure(FeatureContext context) { + List> resolvers = context.getConfiguration().getInstances().stream() + .filter(ContextResolver.class::isInstance) + .map(resolver -> (ContextResolver) resolver) + .collect(Collectors.toList()); + @SuppressWarnings("unchecked") + var resolverClasses = context.getConfiguration().getClasses().stream() + .filter(ContextResolver.class::isAssignableFrom) + .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(); + for (ContextResolver resolver : existingResolvers) { + Object result = resolver.getContext(type); + if (result instanceof Jsonb) { + return (Jsonb) result; + } + } + return JsonbBuilder.create(); + }); + } + + private void instantiateResolverClasses() { + if (!existingResolverClasses.isEmpty()) { + existingResolverClasses.stream().map(injectionManager::getInstance) + .filter(Objects::nonNull) + .forEach(existingResolvers::add); + existingResolverClasses.clear(); + } + } +} 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..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 @@ -41,7 +41,9 @@ package org.glassfish.weld.services; +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; @@ -148,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 ) + 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!) @@ -214,7 +219,7 @@ public void aroundInject(InjectionContext injectionContext) { } else { injectionManager.injectInstance(target, compEnvManager.getComponentEnvId(injectionEnv),false); } - } else { + } else if (isValidBundleContext()) { if ( target == null ) { injectionManager.injectClass(targetClass, injectionEnv, false); } else { @@ -234,7 +239,7 @@ public void aroundInject(InjectionContext injectionContext) { @Override public void registerInjectionTarget(InjectionTarget injectionTarget, AnnotatedType annotatedType) { - if ( bundleContext instanceof EjbBundleDescriptor ) { + 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. @@ -474,7 +479,12 @@ private String getJndiName( String lookup, String mappedName, String name ) { return jndiName; } - + private boolean isValidBundleContext() { + if (bundleContext instanceof Application || bundleContext instanceof ConnectorDescriptor) { + return false; + } + return true; + } @Override public void cleanup() { 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/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"); 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..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,15 +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>() { - - @Override - protected Deque initialValue() { - return new ArrayDeque<>(5); - } - }; - protected DeploymentLifecycleProbeProvider deploymentLifecycleProbeProvider = null; @@ -291,7 +282,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 +348,7 @@ public void actOn(Logger logger) { } }; + 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 @@ -604,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.get().pop(); + DeploymentUtils.clearCurrentDeploymentContext(); } } ApplicationDeployment depl = new ApplicationDeployment(appInfo, context); @@ -625,6 +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)) { + DeploymentUtils.setCurrentDeploymentContext(context); try (SpanSequence span = tracing.startSequence(DeploymentTracing.AppStage.INITIALIZE)){ notifyLifecycleInterceptorsBefore(ExtendedDeploymentContext.Phase.START, context); appInfo.initialize(); @@ -646,9 +638,9 @@ public void initialize(ApplicationInfo appInfo, Collection sn } else { events.send(new Event<>(Deployment.DEPLOYMENT_SUCCESS, appInfo)); } + DeploymentUtils.clearCurrentDeploymentContext(); } } - currentDeploymentContext.get().pop(); } @Override @@ -1252,6 +1244,7 @@ public ModuleInfo prepareModule( // get the deployer Deployer deployer = engineInfo.getDeployer(); + ExtendedDeploymentContext savedDeploymentContext = DeploymentUtils.getCurrentDeploymentContext(); try (DeploymentSpan span = tracing.startSpan(TraceContext.Level.CONTAINER, engineInfo.getSniffer().getModuleType(), DeploymentTracing.AppStage.PREPARE)){ deployer.prepare(context); @@ -1266,6 +1259,10 @@ public ModuleInfo prepareModule( final ActionReport report = context.getActionReport(); report.failure(logger, "Exception while invoking " + deployer.getClass() + " prepare method", e); throw e; + } finally { + if (getCurrentDeploymentContext() == null) { + DeploymentUtils.setCurrentDeploymentContext(savedDeploymentContext); + } } } @@ -2713,6 +2710,6 @@ public Thread newThread(Runnable r) { @Override public ExtendedDeploymentContext getCurrentDeploymentContext() { - return currentDeploymentContext.get().peek(); + return DeploymentUtils.getCurrentDeploymentContext(); } } 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 } 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) {