From 460aa7c13338149fb38e4ce750285fbe346508c5 Mon Sep 17 00:00:00 2001 From: lprimak Date: Fri, 27 Nov 2020 23:39:26 -0600 Subject: [PATCH 1/5] immutable, serializable, refactored JavaEEContextUtil and added Payara API for EE context --- api/payara-api/pom.xml | 1 + .../fish/payara/context/ContextProducer.java | 171 ++++++++ .../fish/payara/context/Contextualizer.java | 95 +++++ .../deployment/util/ResourceValidator.java | 5 +- .../com/sun/ejb/EjbInvocationFactory.java | 6 +- .../implementation/PayaraValueHolder.java | 22 +- .../extension/ClusteredCDIEventBusImpl.java | 80 ++-- .../appserver/context/CDIExtension.java | 58 +++ .../appserver/context/ContextCDIProducer.java | 72 ++++ .../payara/appserver/context/ContextImpl.java | 21 +- .../appserver/context/ContextualizerImpl.java | 107 +++++ .../context/JavaEEContextUtilImpl.java | 384 ++++++++++++------ .../javax.enterprise.inject.spi.Extension | 1 + .../context/JavaEEContextUtilTest.java | 74 ++++ .../transaction/TransactionScopedCDIUtil.java | 10 +- .../api/invocation/ComponentInvocation.java | 6 +- nucleus/common/internal-api/pom.xml | 5 + .../internal/api/JavaEEContextUtil.java | 76 +--- .../glassfish/internal/data/ModuleInfo.java | 14 +- .../nucleus/config/ClusteredConfig.java | 20 +- .../hazelcast/PayaraHazelcastSerializer.java | 24 +- .../contextproxy/CacheManagerProxy.java | 8 +- .../hazelcast/contextproxy/CacheProxy.java | 84 ++-- .../CompleteConfigurationProxy.java | 22 +- .../contextproxy/EntryProcessorProxy.java | 8 +- 25 files changed, 1032 insertions(+), 342 deletions(-) create mode 100644 api/payara-api/src/main/java/fish/payara/context/ContextProducer.java create mode 100644 api/payara-api/src/main/java/fish/payara/context/Contextualizer.java create mode 100644 appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java create mode 100644 appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java create mode 100644 appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java create mode 100644 appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension create mode 100644 appserver/web/gf-web-connector/src/test/java/fish/payara/appserver/context/JavaEEContextUtilTest.java diff --git a/api/payara-api/pom.xml b/api/payara-api/pom.xml index d2d7c42a406..70e8287460c 100644 --- a/api/payara-api/pom.xml +++ b/api/payara-api/pom.xml @@ -107,6 +107,7 @@ fish.payara.cdi.auth.roles, fish.payara.cdi.jsr107.impl, fish.payara.cluster, + fish.payara.context, fish.payara.jacc, fish.payara.micro.cdi, fish.payara.nucleus.requesttracing.api, diff --git a/api/payara-api/src/main/java/fish/payara/context/ContextProducer.java b/api/payara-api/src/main/java/fish/payara/context/ContextProducer.java new file mode 100644 index 00000000000..eeaf43aeda2 --- /dev/null +++ b/api/payara-api/src/main/java/fish/payara/context/ContextProducer.java @@ -0,0 +1,171 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2020] 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/master/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 fish.payara.context; + +import java.io.Serializable; + +/** + * Utility to create / push Jakarta EE and CDI thread contexts + * + * Example: + * @Inject ContextProducer producer; + * // EJB/CDI thread: + * Instance saved = producer.currentInvocation*(); + * // insure 'saved' is not leaked when application undeployed, + * // otherwise use producer.fromComponentId(producer.getInvocationComponentId()) + * // and in another, non EJB/CDI thread: + * try (Context ctx = saved.pushRequestContext()) { + * // runs with EJB / CDI context + * } + * + * @author lprimak + */ +public interface ContextProducer { + /** + * Creates an empty instance, i.e. if the empty context is pushed + * on top of another context, the other context will be 'suppressed' + * for the duration of this context + * + * @return new empty instance + */ + Instance empty(); + + /** + * captures current invocation and returns it as an instance + * + * @return new captured instance + */ + Instance currentInvocation() throws IllegalStateException; + + /** + * + * @param componentId component id for this instance, non-null + * + * @return new instance based on componentId + */ + Instance fromComponentId(String componentId) throws IllegalArgumentException; + + /** + * @return Class Loader that's associated with current invocation or null if + * there is no current invocation + */ + ClassLoader getInvocationClassLoader(); + + /** + * @return component ID for the current invocation or null + */ + String getInvocationComponentId(); + + /** + * This is different from class loaded, as there are some situations + * where class is loaded but initialization is not complete, + * such as CDI initializations, extensions start, etc. + * + * @return true if current invocation exists and is loaded / ready + */ + boolean isInvocationLoaded(); + + /** + * specific, immutable, thread-safe instance of the context + */ + interface Instance extends Serializable { + /** + * pushes Java EE invocation context onto the invocation stack use + * try-with-resources to pop the context + * no-op if non-running context + * + * @return the new context that was created + */ + Context pushContext(); + + /** + * pushes invocation context onto the stack Also creates Request scope + * use try-with-resources to pop the context + * no-op if non-running context + * + * @return new context that was created + */ + Context pushRequestContext(); + + /** + * set context class loader by component id of this instance + * for empty or unloaded component, class loader remains unset and the + * context is a no-op (no re-set gets done) so it's a no-op + * + * @return context so class loader can be reset + */ + Context setApplicationClassLoader(); + + /** + * @return component ID for the current instance, or null if empty instance + */ + String getInstanceComponentId(); + + /** + * This is different from class loaded, as there are some situations + * where class is loaded but initialization is not complete, such as CDI + * initializations, extensions start, etc. + * + * @return true if component is loaded and starting + */ + boolean isLoaded(); + + /** + * @return true if this is an empty context + */ + boolean isEmpty(); + + /** + * remove cached invocation from this instance, in case the + * underlying app unloaded but component ID remains, just in case the + * app is reloaded + */ + void clearInstanceInvocation(); + } + + interface Context extends Closeable { + boolean isValid(); + }; + + interface Closeable extends AutoCloseable { + @Override + public void close(); + } +} diff --git a/api/payara-api/src/main/java/fish/payara/context/Contextualizer.java b/api/payara-api/src/main/java/fish/payara/context/Contextualizer.java new file mode 100644 index 00000000000..084673694c5 --- /dev/null +++ b/api/payara-api/src/main/java/fish/payara/context/Contextualizer.java @@ -0,0 +1,95 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2020] 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/master/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 fish.payara.context; + +import java.util.stream.Stream; + +/** + * Wraps an object with a proxy that sets Payara context around + * every method call. This is useful for listeners, callbacks, + * and other objects that run from another thread that may not have + * Payara context initialized. + * + * This was create primarily to facilitate integration with Hazelcast, + * which has listeners that do not capture Payara context. + * + * Example: + * @Inject Contextualizer contextualizer; + * @Inject MyListener myListener; + * + * // runs myListener.listen() method in a separate thread, + * // with context captured from current thread + * new Thread(contextualizer.contextualize(() -> myListener.listen(), Runnable.class)); + * + * @author lprimak + */ +public interface Contextualizer { + /** + * Wraps an object in a proxy that preserves Payara context + * + * @param object type to proxy and contextualize + * @param object object instance to proxy and contextualize + * @param intf Interface that is used to proxy the object + * @return proxied object + */ + T contextualize(T object, Class intf); + + /** + * Wraps an object in a proxy that preserves Payara context + * + * @param + * @param object + * @param context + * @param intf + * @return proxied object + */ + T contextualize(T object, ContextProducer.Instance context, Class intf); + + /** + * Wraps an object in a proxy that preserves Payara context + * + * @param + * @param object + * @param context + * @param interfaces + * @return proxied object + */ + T contextualize(T object, ContextProducer.Instance context, Stream> interfaces); +} diff --git a/appserver/deployment/dol/src/main/java/com/sun/enterprise/deployment/util/ResourceValidator.java b/appserver/deployment/dol/src/main/java/com/sun/enterprise/deployment/util/ResourceValidator.java index f5a9d667b24..dd65d6b49a8 100644 --- a/appserver/deployment/dol/src/main/java/com/sun/enterprise/deployment/util/ResourceValidator.java +++ b/appserver/deployment/dol/src/main/java/com/sun/enterprise/deployment/util/ResourceValidator.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2016-2019] [Payara Foundation and/or its affiliates] +// Portions Copyright [2016-2020] [Payara Foundation and/or its affiliates] package com.sun.enterprise.deployment.util; @@ -142,8 +142,7 @@ public void event(Event event) { parseResources(deploymentContext, application, appResources); // Ensure we have a valid component invocation before triggering lookups - contextUtil.setEmptyInvocation(); - try (Context ctx = contextUtil.pushContext()) { + try (Context ctx = contextUtil.empty().pushContext()) { validateResources(deploymentContext, application, appResources); } } diff --git a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbInvocationFactory.java b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbInvocationFactory.java index 502a63df663..8864e94ee60 100644 --- a/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbInvocationFactory.java +++ b/appserver/ejb/ejb-container/src/main/java/com/sun/ejb/EjbInvocationFactory.java @@ -37,6 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ +// Portions Copyright [2018-2020] [Payara Foundation and/or its affiliates] package com.sun.ejb; @@ -56,7 +57,9 @@ public EjbInvocationFactory(String compEnvId, Container container) { } public EjbInvocation create() { - return new EjbInvocation(compEnvId, container); + EjbInvocation ejbInv = new EjbInvocation(compEnvId, container); + ejbInv.jndiEnvironment = container.getEjbDescriptor(); + return ejbInv; } public EjbInvocation create(Object ejb, C ctx) { @@ -64,6 +67,7 @@ public EjbInvocation create(Object ejb, C ctx) { ejbInv.ejb = ejb; ejbInv.instance = ejb; ejbInv.context = ctx; + ejbInv.jndiEnvironment = container.getEjbDescriptor(); return ejbInv; } diff --git a/appserver/payara-appserver-modules/payara-jsr107/src/main/java/fish/payara/cdi/jsr107/implementation/PayaraValueHolder.java b/appserver/payara-appserver-modules/payara-jsr107/src/main/java/fish/payara/cdi/jsr107/implementation/PayaraValueHolder.java index 44270e643d3..578ebbc0ba0 100644 --- a/appserver/payara-appserver-modules/payara-jsr107/src/main/java/fish/payara/cdi/jsr107/implementation/PayaraValueHolder.java +++ b/appserver/payara-appserver-modules/payara-jsr107/src/main/java/fish/payara/cdi/jsr107/implementation/PayaraValueHolder.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2016-2019 Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) 2016-2020 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 @@ -46,8 +46,10 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectOutputStream; +import java.util.Optional; import org.glassfish.internal.api.Globals; import org.glassfish.internal.api.JavaEEContextUtil; +import org.glassfish.internal.api.JavaEEContextUtil.Context; /** * Packages up an object into a Serializable value @@ -66,7 +68,7 @@ public PayaraValueHolder() { public PayaraValueHolder(T value) throws IOException { try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos)) { - oos.writeObject(Globals.getDefaultHabitat().getService(JavaEEContextUtil.class).getInstanceComponentId()); + oos.writeObject(Globals.getDefaultHabitat().getService(JavaEEContextUtil.class).getInvocationComponentId()); oos.writeObject(value); data = baos.toByteArray(); } @@ -77,17 +79,21 @@ public T getValue() throws IOException, ClassNotFoundException { String componentId = null; try (ByteArrayInputStream bais = new ByteArrayInputStream(data); PayaraTCCLObjectInputStream ois = new PayaraTCCLObjectInputStream(bais)) { componentId = (String)ois.readObject(); - Object result = ois.readObject(); - return (T)result; + JavaEEContextUtil ctxUtil = Globals.getDefaultHabitat().getService(JavaEEContextUtil.class); + JavaEEContextUtil.Instance inst = Optional.ofNullable(componentId) + .map(ctxUtil::fromComponentId).orElse(ctxUtil.empty()); + try (Context ctx = inst.setApplicationClassLoader()) { + return (T) ois.readObject(); + } } catch (ClassNotFoundException ex) { - String invocationComponentId = Globals.getDefaultHabitat().getService(JavaEEContextUtil.class).getInstanceComponentId(); + String invocationComponentId = Globals.getDefaultHabitat().getService(JavaEEContextUtil.class).getInvocationComponentId(); if (componentId == null){ componentId = ""; } - if (componentId.equals(invocationComponentId)) { - throw new ClassNotFoundException(String.format("Wrong application: expected %s bug got %s", componentId, invocationComponentId), - new IllegalStateException("Wrong Application")); + if (!componentId.equals(invocationComponentId)) { + throw new ClassNotFoundException(String.format("Wrong application: expected %s but got %s", componentId, invocationComponentId), + new IllegalStateException("Wrong Application", ex)); } else { throw ex; } diff --git a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/ClusteredCDIEventBusImpl.java b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/ClusteredCDIEventBusImpl.java index 795b22ecb14..d3018322a26 100644 --- a/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/ClusteredCDIEventBusImpl.java +++ b/appserver/payara-appserver-modules/payara-micro-cdi/src/main/java/fish/payara/micro/cdi/extension/ClusteredCDIEventBusImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2016-2018 Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) 2016-2020 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 @@ -39,8 +39,6 @@ */ package fish.payara.micro.cdi.extension; -import com.sun.enterprise.deployment.JndiNameEnvironment; -import com.sun.enterprise.deployment.util.DOLUtils; import com.sun.enterprise.util.Utility; import fish.payara.micro.cdi.Outbound; import fish.payara.micro.cdi.Inbound; @@ -58,7 +56,6 @@ import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import javax.annotation.Resource; import javax.enterprise.concurrent.ManagedExecutorService; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Initialized; @@ -71,8 +68,6 @@ import org.glassfish.internal.api.Globals; import org.glassfish.internal.api.JavaEEContextUtil; import org.glassfish.internal.api.JavaEEContextUtil.Context; -import org.glassfish.internal.deployment.Deployment; -import org.glassfish.internal.deployment.ExtendedDeploymentContext; /** * @@ -89,7 +84,7 @@ public class ClusteredCDIEventBusImpl implements CDIEventListener, ClusteredCDIE private ManagedExecutorService managedExecutorService; - private JavaEEContextUtil ctxUtil; + private JavaEEContextUtil.Instance ctxUtil; private final static String INSTANCE_PROPERTY = "InstanceName"; @@ -97,7 +92,7 @@ public class ClusteredCDIEventBusImpl implements CDIEventListener, ClusteredCDIE @PostConstruct void postConstruct() { - ctxUtil = Globals.getDefaultHabitat().getService(JavaEEContextUtil.class); + ctxUtil = Globals.getDefaultHabitat().getService(JavaEEContextUtil.class).currentInvocation(); try { InitialContext ctx = new InitialContext(); managedExecutorService = (ManagedExecutorService) ctx.lookup("java:comp/DefaultManagedExecutorService"); @@ -144,50 +139,39 @@ public void eventReceived(final PayaraClusteredCDIEvent event) { } try(Context ctx = ctxUtil.pushContext()) { - managedExecutorService.submit(new Runnable() { - @Override - public void run() { - ClassLoader oldCL = Utility.getClassLoader(); - try { - ClassLoader invocationClassLoader = ctxUtil.getInvocationClassLoader(); - if (invocationClassLoader != null) { // null in case of an event from server such as CDI notifier - Utility.setContextClassLoader(invocationClassLoader); + managedExecutorService.submit(() -> { + try (final Context ctx1 = ctxUtil.setApplicationClassLoader()) { + // create the set of qualifiers for the event + // first add Inbound qualifier with the correct properties + Set qualifiers = new HashSet<>(); + Serializable eventPayload = event.getPayload(); + Inbound inbound = new Inbound() { + @Override + public String eventName() { + return event.getProperty(EVENT_PROPERTY); } - // create the set of qualifiers for the event - // first add Inbound qualifier with the correct properties - Set qualifiers = new HashSet<>(); - Serializable eventPayload = event.getPayload(); - Inbound inbound = new Inbound() { - @Override - public String eventName() { - return event.getProperty(EVENT_PROPERTY); - } - - @Override - public Class annotationType() { - return Inbound.class; - } - }; - qualifiers.add(inbound); - - // Now create Qualifiers for the sent event qualifiers - Set receivedQualifiers = event.getQualifiers(); - for (Annotation receivedQualifier : receivedQualifiers) { - // strip out OutBound as we don't want it even though it was sent over - if (!(receivedQualifier instanceof Outbound)) { - qualifiers.add(receivedQualifier); - } + @Override + public Class annotationType() { + return Inbound.class; + } + }; + qualifiers.add(inbound); + + // Now create Qualifiers for the sent event qualifiers + Set receivedQualifiers = event.getQualifiers(); + for (Annotation receivedQualifier : receivedQualifiers) { + // strip out OutBound as we don't want it even though it was sent over + if (!(receivedQualifier instanceof Outbound)) { + qualifiers.add(receivedQualifier); } - Annotation annotations[] = qualifiers.toArray(new Annotation[0]); - bm.fireEvent(eventPayload,annotations); - } catch (IOException | ClassNotFoundException ex) { - Logger.getLogger(ClusteredCDIEventBusImpl.class.getName()) - .log(ex.getCause() instanceof IllegalStateException? Level.FINE : Level.INFO, - "Received Event but could not process it", ex); - } finally { - Utility.setContextClassLoader(oldCL); } + Annotation annotations[] = qualifiers.toArray(new Annotation[0]); + bm.fireEvent(eventPayload,annotations); + } catch (IOException | ClassNotFoundException ex) { + Logger.getLogger(ClusteredCDIEventBusImpl.class.getName()) + .log(ex.getCause() instanceof IllegalStateException? Level.FINE : Level.INFO, + "Received Event but could not process it", ex); } }); } diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java new file mode 100644 index 00000000000..e409a701ac5 --- /dev/null +++ b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java @@ -0,0 +1,58 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2020] 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/master/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 fish.payara.appserver.context; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.BeforeBeanDiscovery; +import javax.enterprise.inject.spi.Extension; + +/** + * adds context producer + * + * @author lprimak + */ +public class CDIExtension implements Extension { + void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager bm) { + AnnotatedType at = bm.createAnnotatedType(ContextCDIProducer.class); + bbd.addAnnotatedType(at, ContextCDIProducer.class.getName()); + } +} diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java new file mode 100644 index 00000000000..d83ed7c66e3 --- /dev/null +++ b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java @@ -0,0 +1,72 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2020] 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/master/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 fish.payara.appserver.context; + +import fish.payara.context.ContextProducer; +import fish.payara.context.Contextualizer; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import org.glassfish.internal.api.Globals; +import org.glassfish.internal.api.JavaEEContextUtil; + +/** + * CDI producer for context + * + * @author lprimak + */ +public class ContextCDIProducer { + private final ContextProducer contextproducer = Globals.getDefaultHabitat() + .getService(JavaEEContextUtil.class); + private final Contextualizer contextualizer = Globals.getDefaultHabitat() + .getService(ContextualizerImpl.class); + + + @Produces + @ApplicationScoped + Contextualizer getContextualizer() { + return contextualizer; + } + + @Produces + @ApplicationScoped + ContextProducer getContextProducer() { + return contextproducer; + } +} diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextImpl.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextImpl.java index 858ae285b88..c326aeb802a 100644 --- a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextImpl.java +++ b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] 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 @@ -39,6 +39,7 @@ */ package fish.payara.appserver.context; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; import com.sun.enterprise.util.Utility; import java.util.Map; import org.glassfish.api.invocation.ComponentInvocation; @@ -52,7 +53,6 @@ * @author lprimak */ class ContextImpl { - public static class Context implements JavaEEContextUtil.Context { @Override public void close() { @@ -62,13 +62,23 @@ public void close() { } } + @Override + public boolean isValid() { + return invocation != null && !JavaEEContextUtilImpl.isLeaked(compEnvMgr, + invocation, invocation.getComponentId()); + } + + private final ComponentInvocation invocation; private final InvocationManager invMgr; + private final ComponentEnvManager compEnvMgr; private final ClassLoader oldClassLoader; - public Context(ComponentInvocation invocation, InvocationManager invMgr, ClassLoader oldClassLoader) { + public Context(ComponentInvocation invocation, InvocationManager invMgr, ComponentEnvManager compEnvMgr, + ClassLoader oldClassLoader) { this.invocation = invocation; this.invMgr = invMgr; + this.compEnvMgr = compEnvMgr; this.oldClassLoader = oldClassLoader; } } @@ -111,5 +121,10 @@ public RequestContext(org.glassfish.internal.api.JavaEEContextUtil.Context rootC this.ctx = ctx; this.storage = storage; } + + @Override + public boolean isValid() { + return rootCtx.isValid(); + } } } diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java new file mode 100644 index 00000000000..9373055284c --- /dev/null +++ b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java @@ -0,0 +1,107 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2020] 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/master/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 fish.payara.appserver.context; + +import fish.payara.context.ContextProducer; +import fish.payara.context.Contextualizer; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.stream.Stream; +import javax.inject.Inject; +import org.glassfish.internal.api.JavaEEContextUtil; +import org.jvnet.hk2.annotations.Service; + +/** + * + * @author lprimak + */ +@Service +public class ContextualizerImpl implements Contextualizer { + @Inject + private JavaEEContextUtil ctxUtil; + + @Override + @SuppressWarnings("unchecked") + public T contextualize(T object, Class intf) { + return contextualize(object, ctxUtil.currentInvocation(), Stream.of(intf)); + } + + @Override + @SuppressWarnings("unchecked") + public T contextualize(T object, ContextProducer.Instance context, Class intf) { + return contextualize(object, context, Stream.of(intf)); + } + + @Override + @SuppressWarnings("unchecked") + public T contextualize(T object, ContextProducer.Instance context, Stream> interfaces) { + return (T) Proxy.newProxyInstance(ctxUtil.getInvocationClassLoader(), interfaces.toArray(Class[]::new), + new InvocationHandlerImpl(context, object)); + } + + public class InvocationHandlerImpl implements InvocationHandler { + private final ContextProducer.Instance inv; + private final Object delegate; + private boolean ignore; + + + private InvocationHandlerImpl(ContextProducer.Instance currentInvocation, Object delegate) { + this.inv = currentInvocation; + this.delegate = delegate; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try (ContextProducer.Context ctx = inv.pushRequestContext()) { + if (!ignore && ctx.isValid()) { + return method.invoke(delegate, args); + } else { + // first time the context is invalid, never run again! + // class loader is fixed the moment it leaks, so the + // subsequent calls would be with the correct class loader + // however delegate would be still out of date + ignore = true; + return null; + } + } + } + } +} diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/JavaEEContextUtilImpl.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/JavaEEContextUtilImpl.java index 96acd54b90b..226d273a0e3 100644 --- a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/JavaEEContextUtilImpl.java +++ b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/JavaEEContextUtilImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] 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 @@ -43,19 +43,21 @@ import com.sun.enterprise.deployment.BundleDescriptor; import com.sun.enterprise.deployment.EjbDescriptor; import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.enterprise.deployment.util.DOLUtils; import com.sun.enterprise.util.Utility; -import java.io.IOException; -import java.io.ObjectInputStream; import java.io.Serializable; +import java.lang.reflect.Proxy; +import java.util.Collection; import org.glassfish.internal.api.JavaEEContextUtil; import java.util.HashMap; -import javax.annotation.PostConstruct; import javax.enterprise.inject.spi.CDI; +import javax.inject.Inject; import org.glassfish.api.invocation.ComponentInvocation; import org.glassfish.api.invocation.InvocationManager; -import org.glassfish.hk2.api.PerLookup; import org.glassfish.internal.api.Globals; -import org.glassfish.internal.api.ServerContext; +import org.glassfish.internal.data.ApplicationInfo; +import org.glassfish.internal.data.ApplicationRegistry; +import org.glassfish.internal.data.ModuleInfo; import org.jboss.weld.context.bound.BoundRequestContext; import org.jvnet.hk2.annotations.Service; @@ -65,98 +67,37 @@ * @author lprimak */ @Service -@PerLookup public class JavaEEContextUtilImpl implements JavaEEContextUtil, Serializable { - private transient ServerContext serverContext; - private transient ComponentEnvManager compEnvMgr; - private transient ComponentInvocation capturedInvocation; - private String instanceComponentId; - private static final String EMPTY_COMPONENT = "___EMPTY___"; - private static final long serialVersionUID = 1L; - - @PostConstruct - void init() { - serverContext = Globals.getDefaultHabitat().getService(ServerContext.class); - compEnvMgr = Globals.getDefaultHabitat().getService(ComponentEnvManager.class); + private static final long serialVersionUID = 2L; - doSetInstanceContext(); - } + @Inject + private transient ComponentEnvManager compEnvMgr; + @Inject + private transient ApplicationRegistry appRegistry; + @Inject + private transient InvocationManager invocationManager; - protected ServerContext getServerContext() { - return serverContext; - } @Override - public String getInstanceComponentId() { - return instanceComponentId; - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - init(); + public Instance empty() { + return new InstanceImpl(); } - /** - * pushes Java EE invocation context - * - * @return the new context - */ @Override - public Context pushContext() { - InvocationManager invMgr = serverContext.getInvocationManager(); - boolean invocationCreated = false; - if (invMgr.getCurrentInvocation() == null && capturedInvocation != null) { - ComponentInvocation newInvocation = capturedInvocation.clone(); - newInvocation.clearRegistry(); - invMgr.preInvoke(newInvocation); - invocationCreated = true; - } - ClassLoader oldClassLoader = null; - if (invocationCreated) { - if (EMPTY_COMPONENT.equals(getInstanceComponentId())) { - oldClassLoader = Utility.getClassLoader(); - } - else { - oldClassLoader = Utility.setContextClassLoader(getInvocationClassLoader()); - } + public Instance currentInvocation() { + ComponentInvocation currentInvocation = invocationManager.getCurrentInvocation(); + if (currentInvocation == null) { + throw new IllegalStateException("No Current Invocation present"); } - return new ContextImpl.Context(invocationCreated? invMgr.getCurrentInvocation() : null, invMgr, oldClassLoader); + return new InstanceImpl(currentInvocation); } - /** - * pushes invocation context onto the stack - * Also creates Request scope - * - * @return new context that was created - */ @Override - public Context pushRequestContext() { - Context rootCtx = pushContext(); - BoundRequestContext brc = CDI.current().select(BoundRequestContext.class).get(); - ContextImpl.RequestContext context = new ContextImpl.RequestContext(rootCtx, brc.isActive()? null : brc, new HashMap<>()); - if (context.ctx != null) { - context.ctx.associate(context.storage); - context.ctx.activate(); - } - return context; - } - - /** - * set context class loader by component ID - */ - @Override - public Context setApplicationClassLoader() { - ClassLoader cl = null; - if (capturedInvocation != null && capturedInvocation.getJNDIEnvironment() != null) { - cl = getClassLoaderForEnvironment((JndiNameEnvironment)capturedInvocation.getJNDIEnvironment()); - } - else if (instanceComponentId != null) { - cl = getClassLoaderForEnvironment(compEnvMgr.getJndiNameEnvironment(instanceComponentId)); - } - if (cl != null) { - return new ContextImpl.ClassLoaderContext(Utility.setContextClassLoader(cl), true); + public Instance fromComponentId(String componentId) throws IllegalArgumentException { + if (componentId == null) { + throw new IllegalArgumentException("componentId cannot be null"); } - return new ContextImpl.ClassLoaderContext(null, false); + return new InstanceImpl(componentId); } @Override @@ -165,74 +106,249 @@ public ClassLoader getInvocationClassLoader() { return getClassLoaderForEnvironment(componentEnv); } - @Override - public void setInstanceContext() { - instanceComponentId = null; - doSetInstanceContext(); - } - - @Override - public void setEmptyInvocation() { - instanceComponentId = EMPTY_COMPONENT; - capturedInvocation = createInvocation(null); - } - @Override public String getInvocationComponentId() { - ComponentInvocation inv = serverContext.getInvocationManager().getCurrentInvocation(); + ComponentInvocation inv = invocationManager.getCurrentInvocation(); return inv != null? inv.getComponentId() : null; } @Override - public JavaEEContextUtil setInstanceComponentId(String componentId) { - this.instanceComponentId = componentId; - if (componentId != null) { - createInvocationContext(); - } - else { - capturedInvocation = null; - } - return this; + public boolean isInvocationLoaded() { + ComponentInvocation inv = invocationManager.getCurrentInvocation(); + return inv != null ? isLoaded(inv.getComponentId(), inv) : false; } - private void doSetInstanceContext() { - capturedInvocation = serverContext.getInvocationManager().getCurrentInvocation(); - if (capturedInvocation != null) { - capturedInvocation = capturedInvocation.clone(); - instanceComponentId = capturedInvocation.getComponentId(); - } - else if (instanceComponentId != null) { - // deserialized version - createInvocationContext(); - } - } - - private ClassLoader getClassLoaderForEnvironment(JndiNameEnvironment componentEnv) { + private static ClassLoader getClassLoaderForEnvironment(JndiNameEnvironment componentEnv) { if (componentEnv instanceof BundleDescriptor) { - BundleDescriptor bd = (BundleDescriptor)componentEnv; + BundleDescriptor bd = (BundleDescriptor) componentEnv; return bd.getClassLoader(); } else if (componentEnv instanceof EjbDescriptor) { - EjbDescriptor ed = (EjbDescriptor)componentEnv; + EjbDescriptor ed = (EjbDescriptor) componentEnv; return ed.getEjbBundleDescriptor().getClassLoader(); } return null; } - private void createInvocationContext() { - JndiNameEnvironment jndiEnv = compEnvMgr.getJndiNameEnvironment(instanceComponentId); - if (jndiEnv != null) { // create invocation only for valid JNDI environment - capturedInvocation = createInvocation(jndiEnv); - } - else { - capturedInvocation = null; - } - } - - private ComponentInvocation createInvocation(JndiNameEnvironment jndiEnv) { + private ComponentInvocation createInvocation(JndiNameEnvironment jndiEnv, String componentId) { ComponentInvocation newInvocation = new ComponentInvocation(); - newInvocation.componentId = instanceComponentId; + newInvocation.componentId = componentId; newInvocation.setJNDIEnvironment(jndiEnv); newInvocation.setComponentInvocationType(ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION); return newInvocation; } + + private boolean isLoaded(String componentId, ComponentInvocation invocation) { + if (componentId == null) { + // empty component are always loaded + return true; + } + JndiNameEnvironment env = invocation != null ? ((JndiNameEnvironment) invocation.getJNDIEnvironment()) + : compEnvMgr.getJndiNameEnvironment(componentId); + if (env != null) { + ApplicationInfo appInfo = appRegistry.get(DOLUtils.getApplicationFromEnv(env).getRegistrationName()); + Collection modules = appInfo.getModuleInfos(); + String moduleName = DOLUtils.getModuleName(env); + if (modules.stream().filter(mod -> mod.getName().equals(moduleName)) + .anyMatch(moduleInfo -> !moduleInfo.isLoaded())) { + return false; + } + } + return env != null; + } + + static boolean isLeaked(ComponentEnvManager compEnvMgr, ComponentInvocation cachedInvocation, String componentId) { + if (cachedInvocation != null) { + if (getClassLoaderForEnvironment((JndiNameEnvironment) cachedInvocation + .getJNDIEnvironment()) != getClassLoaderForEnvironment(compEnvMgr. + getJndiNameEnvironment(componentId))) { + // referencing old class loader / environment, remove it + return true; + } + } + return false; + } + + // deals with @Injected transient fields correctly + private Object readResolve() { + return Globals.getDefaultHabitat().getService(JavaEEContextUtil.class); + } + + + public class InstanceImpl implements Instance { + private static final long serialVersionUID = 1L; + private final String componentId; + private volatile transient ComponentInvocation cachedInvocation; + private volatile transient boolean loaded; + + + /** + * empty invocation + */ + private InstanceImpl() { + // empty + componentId = null; + checkState(); + } + + /** + * instance from current invocation + * + * @param currentInvocation non-null current invocation + */ + private InstanceImpl(ComponentInvocation currentInvocation) { + boolean isApplicationComponent = false; + if (currentInvocation.getComponentId() != null) { + componentId = currentInvocation.getComponentId(); + } else if (currentInvocation.getJNDIEnvironment() instanceof JndiNameEnvironment) { + componentId = DOLUtils.getApplicationName((JndiNameEnvironment)currentInvocation.jndiEnvironment); + isApplicationComponent = true; + } else { + // checkState() later should error out due to this condition + componentId = null; + } + cachedInvocation = currentInvocation.clone(); + if (isApplicationComponent) { + // application components don't have component ID, just application name + // here we set component ID on the cached object to application name so internal state + // is set correctly + cachedInvocation.setComponentId(componentId); + } + cachedInvocation.clearRegistry(); + checkState(); + } + + private InstanceImpl(String componentId) { + this.componentId = componentId; + checkState(); + } + + @Override + public Context pushContext() { + if (isEmpty()) { + return pushEmptyContext(); + } + if (!isValidAndNotEmpty()) { + // same as invocation, or app not running + return new ContextImpl.Context(null, invocationManager, compEnvMgr, null); + } + ComponentInvocation newInvocation = ensureCached(true).clone(); + invocationManager.preInvoke(newInvocation); + return new ContextImpl.Context(newInvocation, invocationManager, compEnvMgr, + Utility.setContextClassLoader(getInvocationClassLoader())); + } + + private Context pushEmptyContext() { + JndiNameEnvironment env = (JndiNameEnvironment)Proxy.newProxyInstance(Utility.getClassLoader(), + new Class[] { JndiNameEnvironment.class }, (proxy, method, args) -> null); + ComponentInvocation newInvocation = createInvocation(env, "___EMPTY___"); + invocationManager.preInvoke(newInvocation); + return new ContextImpl.Context(newInvocation, invocationManager, compEnvMgr, Utility.getClassLoader()); + } + + @Override + public Context pushRequestContext() { + Context rootCtx = pushContext(); + if (!isValidAndNotEmpty()) { + return rootCtx; + } + BoundRequestContext brc; + try { + brc = CDI.current().select(BoundRequestContext.class).get(); + } catch (Throwable ex) { + return rootCtx; + } + ContextImpl.RequestContext context = new ContextImpl.RequestContext(rootCtx, brc.isActive() ? null : brc, new HashMap<>()); + if (context.ctx != null) { + context.ctx.associate(context.storage); + context.ctx.activate(); + } + return context; + } + + @Override + public Context setApplicationClassLoader() { + ClassLoader cl = null; + ComponentInvocation localCachedInvocation = ensureCached(false); + if (localCachedInvocation != null) { + cl = getClassLoaderForEnvironment((JndiNameEnvironment) localCachedInvocation.getJNDIEnvironment()); + } else if (componentId != null) { + cl = getClassLoaderForEnvironment(compEnvMgr.getJndiNameEnvironment(componentId)); + } + if (cl != null) { + return new ContextImpl.ClassLoaderContext(Utility.setContextClassLoader(cl), true); + } + return new ContextImpl.ClassLoaderContext(null, false); + } + + @Override + public String getInstanceComponentId() { + return componentId; + } + + private ComponentInvocation ensureCached(boolean failOnError) { + ComponentInvocation localCachedInvocation = cachedInvocation; + // empty objects not allowed + if (localCachedInvocation != null || isEmpty()) { + return localCachedInvocation; + } + JndiNameEnvironment jndiEnv = compEnvMgr.getJndiNameEnvironment(componentId); + if (jndiEnv != null) { // create invocation only for valid JNDI environment + localCachedInvocation = createInvocation(jndiEnv, componentId); + cachedInvocation = localCachedInvocation; + } else if (failOnError) { + throw new IllegalStateException(String.format("Cannot cache invocation: %s", componentId)); + } + checkState(); + return localCachedInvocation; + } + + @Override + public boolean isLoaded() { + if (!loaded) { + loaded = JavaEEContextUtilImpl.this.isLoaded(componentId, cachedInvocation); + } + return loaded; + } + + @Override + public boolean isEmpty() { + return componentId == null; + } + + @Override + public void clearInstanceInvocation() { + loaded = false; + cachedInvocation = null; + } + + private boolean isValidAndNotEmpty() { + return isCurrentInvocationPresentAndSame() || isLoaded(); + } + + private boolean isCurrentInvocationPresentAndSame() { + ComponentInvocation invocation = invocationManager.getCurrentInvocation(); + if (invocation != null) { + return componentId != null && componentId.equals(invocation.getComponentId()); + } else { + return false; + } + } + + private void checkState() { + ComponentInvocation localCachedInvocation = cachedInvocation; + if (componentId == null && localCachedInvocation != null) { + // empty invocation + throw new IllegalStateException("Cannot have non-null cached invocation for an empty component"); + } + if (localCachedInvocation != null) { + // check for validity of cached invocation + if (localCachedInvocation.getComponentId() == null || localCachedInvocation.getJNDIEnvironment() == null) { + throw new IllegalStateException("Invalid Cached Invocation - either componentID or JNDIEnvironment is null"); + } + } + if (loaded && localCachedInvocation == null) { + throw new IllegalStateException("running/loaded invocation with null cache"); + } + } + } } diff --git a/appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 00000000000..cdbfb265970 --- /dev/null +++ b/appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +fish.payara.appserver.context.CDIExtension \ No newline at end of file diff --git a/appserver/web/gf-web-connector/src/test/java/fish/payara/appserver/context/JavaEEContextUtilTest.java b/appserver/web/gf-web-connector/src/test/java/fish/payara/appserver/context/JavaEEContextUtilTest.java new file mode 100644 index 00000000000..be72817e9e9 --- /dev/null +++ b/appserver/web/gf-web-connector/src/test/java/fish/payara/appserver/context/JavaEEContextUtilTest.java @@ -0,0 +1,74 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) [2018-2020] 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/master/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 fish.payara.appserver.context; + +import com.sun.enterprise.util.Utility; +import org.glassfish.internal.api.JavaEEContextUtil; +import org.glassfish.internal.api.JavaEEContextUtil.Context; +import org.glassfish.internal.api.JavaEEContextUtil.Instance; +import org.junit.Before; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author lprimak + */ +public class JavaEEContextUtilTest { + private JavaEEContextUtil ctxUtil; + @Before + public void setUp() { + ctxUtil = new JavaEEContextUtilImpl(); + } + + @Test + public void empty() { + Instance empty = ctxUtil.empty(); + assertTrue(empty.isEmpty()); + assertTrue(empty.isLoaded()); + assertNull(empty.getInstanceComponentId()); + ClassLoader cl = Utility.getClassLoader(); + try (Context ctx = empty.setApplicationClassLoader()) { + assertEquals("inside empty context", Utility.getClassLoader(), cl); + } + assertEquals("outside empty context", Utility.getClassLoader(), cl); + } +} diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java b/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java index c3020bb3537..62956a9a64c 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -// Portions Copyright [2017-2018] [Payara Foundation and/or its affiliates] +// Portions Copyright [2017-2020] [Payara Foundation and/or its affiliates] package org.glassfish.cdi.transaction; @@ -202,7 +202,7 @@ private static class BeanWrapper implements Bean { private Class beanClass; private InjectionTarget injectionTarget = null; - private final Optional ctxUtil; + private final Optional ctxUtil; public BeanWrapper(Class beanClass) { this.beanClass = beanClass; @@ -219,7 +219,7 @@ public BeanWrapper(Class beanClass) { catch(MultiException e) { log(e.getMessage()); } - this.ctxUtil = ctxUtil; + this.ctxUtil = ctxUtil.map(util -> util.currentInvocation()); } private void setInjectionTarget(InjectionTarget injectionTarget) { @@ -288,7 +288,7 @@ public boolean isNullable() { @Override public Object create(CreationalContext ctx) { - try (Context eeCtx = ctxUtil.isPresent()? ctxUtil.get().pushContext() : null) { + try (Context eeCtx = ctxUtil.isPresent() ? ctxUtil.get().pushContext() : null) { Object instance = injectionTarget.produce(ctx); injectionTarget.inject(instance, ctx); injectionTarget.postConstruct(instance); @@ -298,7 +298,7 @@ public Object create(CreationalContext ctx) { @Override public void destroy(Object instance, CreationalContext ctx) { - try (Context eeCtx = ctxUtil.isPresent()? ctxUtil.get().pushContext() : null) { + try (Context eeCtx = ctxUtil.isPresent() ? ctxUtil.get().pushContext() : null) { injectionTarget.preDestroy(instance); injectionTarget.dispose(instance); } diff --git a/nucleus/common/glassfish-api/src/main/java/org/glassfish/api/invocation/ComponentInvocation.java b/nucleus/common/glassfish-api/src/main/java/org/glassfish/api/invocation/ComponentInvocation.java index 9b90a0b1317..594ab913dcc 100644 --- a/nucleus/common/glassfish-api/src/main/java/org/glassfish/api/invocation/ComponentInvocation.java +++ b/nucleus/common/glassfish-api/src/main/java/org/glassfish/api/invocation/ComponentInvocation.java @@ -337,18 +337,18 @@ public ResourceHandler getResourceHandler() { /** * @return Registry associated with this invocation for the given key */ - public Object getRegistryFor(Class key) { + public T getRegistryFor(Class key) { if (registry == null) { return null; } else { - return registry.get(key); + return (T)registry.get(key); } } /** * Associate given registry with given key for this invocation */ - public void setRegistryFor(Class key, Object payLoad) { + public void setRegistryFor(Class key, T payLoad) { if (registry == null) { registry = new HashMap<>(); } diff --git a/nucleus/common/internal-api/pom.xml b/nucleus/common/internal-api/pom.xml index a6aadae8e84..7e6446e1315 100644 --- a/nucleus/common/internal-api/pom.xml +++ b/nucleus/common/internal-api/pom.xml @@ -101,6 +101,11 @@ org.glassfish.hk2 class-model + + fish.payara.api + payara-api + ${project.version} + fish.payara.server.internal.common glassfish-api diff --git a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java index 975929ae7d4..e135174c2a3 100644 --- a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) [2016-2019] Payara Foundation and/or its affiliates. All rights reserved. + * Copyright (c) [2016-2020] 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 @@ -39,6 +39,7 @@ */ package org.glassfish.internal.api; +import fish.payara.context.ContextProducer; import org.jvnet.hk2.annotations.Contract; /** @@ -47,68 +48,21 @@ * @author lprimak */ @Contract -public interface JavaEEContextUtil { - /** - * pushes Java EE invocation context onto the invocation stack - * use try-with-resources to pop the context - * - * @return the new context that was created - */ - Context pushContext(); +public interface JavaEEContextUtil extends ContextProducer { + @Override Instance empty(); + @Override Instance currentInvocation() throws IllegalStateException; + @Override Instance fromComponentId(String componentId) throws IllegalArgumentException; - /** - * pushes invocation context onto the stack - * Also creates Request scope - * use try-with-resources to pop the context - * - * @return new context that was created - */ - Context pushRequestContext(); - - /** - * set context class loader by internal state of this instance - * @return context so class loader can be reset - */ - Context setApplicationClassLoader(); - - /** - * Sets the state of this instance from current invocation context - */ - void setInstanceContext(); - - /** - * sets component ID for this instance and re-generates the invocation based on it - * - * @param componentId - * @return self for fluent API - */ - JavaEEContextUtil setInstanceComponentId(String componentId); - - /** - * @return Class Loader that's associated with current invocation - * or null if there is no current invocation - */ - - ClassLoader getInvocationClassLoader(); - /** - * @return component ID for the current invocation (not this instance), or null - */ - String getInvocationComponentId(); - - /** - * @return component ID for the current instance, or null - */ - String getInstanceComponentId(); - - /** - * Set a valid component invocation that's empty, - * i.e. doesn't belong to any module - */ - void setEmptyInvocation(); + interface Instance extends ContextProducer.Instance { + @Override Context pushContext(); + @Override Context pushRequestContext(); + @Override Context setApplicationClassLoader(); + } - interface Context extends Closeable {}; - interface Closeable extends AutoCloseable { + interface Context extends ContextProducer.Context { @Override - public void close(); + default boolean isValid() { + return true; + } } } diff --git a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/data/ModuleInfo.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/data/ModuleInfo.java index 5cfdc708cbf..9600c4332c6 100644 --- a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/data/ModuleInfo.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/data/ModuleInfo.java @@ -101,6 +101,7 @@ public class ModuleInfo { protected final String name; protected final Events events; private Properties moduleProps; + private boolean loaded = false; private boolean started = false; private ClassLoader moduleClassLoader; private Set classLoaders = new HashSet<>(); @@ -163,6 +164,14 @@ public String getName() { return name; } + public boolean isRunning() { + return started; + } + + public boolean isLoaded() { + return loaded; + } + public Properties getModuleProps() { Properties props = new Properties(); if (moduleProps != null) { @@ -268,6 +277,7 @@ public synchronized void start( if (started) return; + loaded = true; ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); StructuredDeploymentTracing tracing = StructuredDeploymentTracing.load(context); @@ -322,7 +332,8 @@ public synchronized void stop(ExtendedDeploymentContext context, Logger logger) engine.getContainerInfo().getSniffer().getModuleType(),e ); } } - started=false; + started = false; + loaded = false; if (events!=null) { events.send(new Event(Deployment.MODULE_STOPPED, this), false); } @@ -441,5 +452,6 @@ public void save(Module module) throws TransactionFailure, PropertyVetoException public void reset() { cleanClassLoaders(); started = false; + loaded = false; } } diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/config/ClusteredConfig.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/config/ClusteredConfig.java index 0ea70f8e8f9..1a45f144aa9 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/config/ClusteredConfig.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/config/ClusteredConfig.java @@ -60,15 +60,15 @@ /** * The {@link ClusteredConfig} can hold configurations that should have a common values that is based on local * configuration values but at the same time accessible to all instances in the cluster. - * + * * Such cases are not supported by the configuration originating from {@code domain.xml}. First of all non DAS instances * only have their own data available. Secondly with micro instances involved multiple instances can see themselves as * the DAS instance each with its own local value. - * + * * This configurations allows to take a local configuration property and share it with the other instances. The * effective value for each instance will be computed from a merge {@link BiFunction} on the basis of the local values * shared by the other instances. - * + * * @author Jan Bernitt * @since 5.201 */ @@ -89,7 +89,7 @@ public class ClusteredConfig extends MembershipAdapter { /** * The names of the {@link ReplicatedMap}s holding the instances values of shared configurations. - * + * * This uses {@link ReplicatedMap}s as responsiveness is important and eventual consistency good enough. */ private final Set sharedConfigurations = ConcurrentHashMap.newKeySet(); @@ -112,14 +112,14 @@ public void preDestroy() { /** * Accesses and merges a shared configuration property. - * + * * Shared configurations are values that use a common value for each instance. The value used is computed by a merge * function from all local values when those become relevant. For example a local value of a disabled feature for * that instance is not relevant and therefore not considered for the shared value. - * + * * In practice this means when an instance is accessing a value that is a common or shared configuration it calls * this method with its local configuration value which makes it effective for this and other instances. - * + * * @param name the globally unique name for the configuration property to read * @param localValue the value as configured locally or a fallback or default value * @param merge the function to use to resolve both local and shared value being present. The resolved value is @@ -146,7 +146,7 @@ public T getSharedConfiguration(String name, T localValue, Bi /** * Can be used to clear the shared value of this instance before the instance is shut down. - * + * * @param name the globally unique name for the configuration property to clear */ public void clearSharedConfiguration(String name) { @@ -154,7 +154,9 @@ public void clearSharedConfiguration(String name) { if (hzInstance != null) { // can be null during shutdown String instance = instanceName(hzInstance.getCluster().getLocalMember()); String mapName = CONFIGURATION_PREFIX + name; - hzInstance.getReplicatedMap(mapName).remove(instance); + if (instance != null) { + hzInstance.getReplicatedMap(mapName).remove(instance); + } } } diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java index 6553fc0276d..ea9f3ea450f 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java @@ -44,8 +44,12 @@ import com.hazelcast.nio.ObjectDataInput; import com.hazelcast.nio.ObjectDataOutput; import com.hazelcast.nio.serialization.StreamSerializer; +import com.sun.enterprise.util.ExceptionUtil; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; import org.glassfish.internal.api.JavaEEContextUtil.Context; +import org.glassfish.internal.api.JavaEEContextUtil.Instance; /** * @@ -53,6 +57,11 @@ * @since 4.1.2.173 */ public class PayaraHazelcastSerializer implements StreamSerializer { + private final JavaEEContextUtil ctxUtil; + private final StreamSerializer delegate; + private static final Logger log = Logger.getLogger(PayaraHazelcastSerializer.class.getName()); + + @SuppressWarnings("unchecked") public PayaraHazelcastSerializer(JavaEEContextUtil ctxUtil, StreamSerializer delegate) { this.ctxUtil = ctxUtil; @@ -70,10 +79,18 @@ public void write(ObjectDataOutput out, Object object) throws IOException { @Override public Object read(ObjectDataInput in) throws IOException { String componentId = (String)delegate.read(in); - ctxUtil.setInstanceComponentId(componentId); - try (Context ctx = ctxUtil.setApplicationClassLoader()) { + Instance context = componentId != null ? ctxUtil.fromComponentId(componentId) : ctxUtil.empty(); + try (Context ctx = context.setApplicationClassLoader()) { return delegate.read(in); } + catch(Throwable ex) { + if (ExceptionUtil.getRootCause(ex) instanceof ClassNotFoundException && !context.isLoaded()) { + log.log(Level.FINE, "Unable to Deserialize - No tenant", ex); + return null; + } else { + throw ex; + } + } } @Override @@ -85,7 +102,4 @@ public int getTypeId() { public void destroy() { delegate.destroy(); } - - private final JavaEEContextUtil ctxUtil; - private final StreamSerializer delegate; } diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheManagerProxy.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheManagerProxy.java index 46079573d27..772c591c5a7 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheManagerProxy.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheManagerProxy.java @@ -64,27 +64,27 @@ public > Cache createCache(String stri Cache cache; JavaEEContextUtil ctxUtil = serverContext.getDefaultServices().getService(JavaEEContextUtil.class); if(ctxUtil != null && config instanceof CompleteConfiguration) { - CompleteConfiguration cfg = new CompleteConfigurationProxy<>((CompleteConfiguration)config, ctxUtil); + CompleteConfiguration cfg = new CompleteConfigurationProxy<>((CompleteConfiguration)config, ctxUtil.currentInvocation()); cache = delegate.createCache(string, cfg); } else { cache = delegate.createCache(string, config); } - return ctxUtil != null? new CacheProxy<>(cache, ctxUtil) : cache; + return ctxUtil != null? new CacheProxy<>(cache, ctxUtil.currentInvocation()) : cache; } @Override public Cache getCache(String cacheName) { JavaEEContextUtil ctxUtil = serverContext.getDefaultServices().getService(JavaEEContextUtil.class); Cache cache = delegate.getCache(cacheName); - return cache != null? new CacheProxy<>(cache, ctxUtil) : null; + return cache != null? new CacheProxy<>(cache, ctxUtil.currentInvocation()) : null; } @Override public Cache getCache(String cacheName, Class keyType, Class valueType) { JavaEEContextUtil ctxUtil = serverContext.getDefaultServices().getService(JavaEEContextUtil.class); Cache cache = delegate.getCache(cacheName, keyType, valueType); - return cache != null? new CacheProxy<>(cache, ctxUtil) : null; + return cache != null? new CacheProxy<>(cache, ctxUtil.currentInvocation()) : null; } diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheProxy.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheProxy.java index 86617b19881..ff063c982ee 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheProxy.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CacheProxy.java @@ -76,31 +76,31 @@ public class CacheProxy implements Cache { private static class CPLProxy implements CompletionListener { @Override public void onCompletion() { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { delegate.onCompletion(); } } @Override public void onException(Exception excptn) { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { delegate.onException(excptn); } } - public CPLProxy(CompletionListener delegate, JavaEEContextUtil ctxUtil) { + public CPLProxy(CompletionListener delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final CompletionListener delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; } @Override public void loadAll(Set set, boolean bln, CompletionListener cl) { if(!(cl instanceof CPLProxy)) { - cl = new CPLProxy(cl, ctxUtil); + cl = new CPLProxy(cl, ctxUtilInst); } delegate.loadAll(set, bln, cl); } @@ -108,7 +108,7 @@ public void loadAll(Set set, boolean bln, CompletionListener cl) { @Override public T invoke(K k, EntryProcessor ep, Object... os) throws EntryProcessorException { if(!(ep instanceof EntryProcessorProxy)) { - ep = new EntryProcessorProxy<>(ep, ctxUtil); + ep = new EntryProcessorProxy<>(ep, ctxUtilInst); } return delegate.invoke(k, ep, os); } @@ -116,7 +116,7 @@ public T invoke(K k, EntryProcessor ep, Object... os) throws EntryP @Override public Map> invokeAll(Set set, EntryProcessor ep, Object... os) { if(!(ep instanceof EntryProcessorProxy)) { - ep = new EntryProcessorProxy<>(ep, ctxUtil); + ep = new EntryProcessorProxy<>(ep, ctxUtilInst); } return delegate.invokeAll(set, ep, os); } @@ -126,7 +126,7 @@ private static class CELProxy implements CacheEntryCreatedListener, @Override public void onCreated(Iterable> itrbl) throws CacheEntryListenerException { CacheEntryCreatedListener listener = (CacheEntryCreatedListener)delegate; - try (Context ctx = ctxUtil.pushRequestContext()) { + try (Context ctx = ctxUtilInst.pushRequestContext()) { listener.onCreated(itrbl); } } @@ -134,7 +134,7 @@ public void onCreated(Iterable> itrbl) @Override public void onExpired(Iterable> itrbl) throws CacheEntryListenerException { CacheEntryExpiredListener listener = (CacheEntryExpiredListener)delegate; - try (Context ctx = ctxUtil.pushRequestContext()) { + try (Context ctx = ctxUtilInst.pushRequestContext()) { listener.onExpired(itrbl); } } @@ -142,7 +142,7 @@ public void onExpired(Iterable> itrbl) @Override public void onRemoved(Iterable> itrbl) throws CacheEntryListenerException { CacheEntryRemovedListener listener = (CacheEntryRemovedListener)delegate; - try (Context ctx = ctxUtil.pushRequestContext()) { + try (Context ctx = ctxUtilInst.pushRequestContext()) { listener.onRemoved(itrbl); } } @@ -150,109 +150,109 @@ public void onRemoved(Iterable> itrbl) @Override public void onUpdated(Iterable> itrbl) throws CacheEntryListenerException { CacheEntryUpdatedListener listener = (CacheEntryUpdatedListener)delegate; - try (Context ctx = ctxUtil.pushRequestContext()) { + try (Context ctx = ctxUtilInst.pushRequestContext()) { listener.onUpdated(itrbl); } } - public CELProxy(CacheEntryListener delegate, JavaEEContextUtil ctxUtil) { + public CELProxy(CacheEntryListener delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final CacheEntryListener delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; } private static class CELFProxy implements Factory> { @Override public CacheEntryListener create() { - try (Context ctx = ctxUtil.pushContext()) { - return new CELProxy<>(delegate.create(), ctxUtil); + try (Context ctx = ctxUtilInst.pushContext()) { + return new CELProxy<>(delegate.create(), ctxUtilInst); } } - public CELFProxy(Factory> delegate, JavaEEContextUtil ctxUtil) { + public CELFProxy(Factory> delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final Factory> delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; private static final long serialVersionUID = 1L; } private static class CEEVProxy implements CacheEntryEventFilter { @Override public boolean evaluate(CacheEntryEvent cee) throws CacheEntryListenerException { - try (Context ctx = ctxUtil.pushRequestContext()) { + try (Context ctx = ctxUtilInst.pushRequestContext()) { return delegate.evaluate(cee); } } - public CEEVProxy(CacheEntryEventFilter delegate, JavaEEContextUtil ctxUtil) { + public CEEVProxy(CacheEntryEventFilter delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final CacheEntryEventFilter delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; } private static class CEEVFProxy implements Factory> { @Override public CacheEntryEventFilter create() { - try (Context ctx = ctxUtil.pushContext()) { - return new CEEVProxy<>(delegate.create(), ctxUtil); + try (Context ctx = ctxUtilInst.pushContext()) { + return new CEEVProxy<>(delegate.create(), ctxUtilInst); } } - public CEEVFProxy(Factory> delegate, JavaEEContextUtil ctxUtil) { + public CEEVFProxy(Factory> delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final Factory> delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; private static final long serialVersionUID = 1L; } private static class CELCProxy implements CacheEntryListenerConfiguration { @Override public Factory> getCacheEntryListenerFactory() { - try (Context ctx = ctxUtil.pushContext()) { - return new CELFProxy<>(delegate.getCacheEntryListenerFactory(), ctxUtil); + try (Context ctx = ctxUtilInst.pushContext()) { + return new CELFProxy<>(delegate.getCacheEntryListenerFactory(), ctxUtilInst); } } @Override public boolean isOldValueRequired() { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { return delegate.isOldValueRequired(); } } @Override public Factory> getCacheEntryEventFilterFactory() { - try (Context ctx = ctxUtil.pushContext()) { - return new CEEVFProxy<>(delegate.getCacheEntryEventFilterFactory(), ctxUtil); + try (Context ctx = ctxUtilInst.pushContext()) { + return new CEEVFProxy<>(delegate.getCacheEntryEventFilterFactory(), ctxUtilInst); } } @Override public boolean isSynchronous() { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { return delegate.isSynchronous(); } } - public CELCProxy(CacheEntryListenerConfiguration delegate, JavaEEContextUtil ctxUtil) { + public CELCProxy(CacheEntryListenerConfiguration delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final CacheEntryListenerConfiguration delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; private static final long serialVersionUID = 1L; } @@ -260,13 +260,13 @@ public CELCProxy(CacheEntryListenerConfiguration delegate, JavaEEContextUt @Override public void registerCacheEntryListener(CacheEntryListenerConfiguration celc) { if(!(celc instanceof CELCProxy)) { - celc = new CELCProxy<>(celc, ctxUtil); + celc = new CELCProxy<>(celc, ctxUtilInst); } delegate.registerCacheEntryListener(celc); } private final Cache delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; @Override public V get(K key) { @@ -278,9 +278,9 @@ public Map getAll(Set keys) { return delegate.getAll(keys); } - public CacheProxy(Cache delegate, JavaEEContextUtil ctxUtil) { + public CacheProxy(Cache delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } @Override diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CompleteConfigurationProxy.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CompleteConfigurationProxy.java index 1beb4fb715d..7a9b4413eb6 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CompleteConfigurationProxy.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/CompleteConfigurationProxy.java @@ -59,9 +59,9 @@ * @author lprimak */ class CompleteConfigurationProxy extends MutableConfiguration { - public CompleteConfigurationProxy(CompleteConfiguration config, JavaEEContextUtil ctxUtil) { + public CompleteConfigurationProxy(CompleteConfiguration config, JavaEEContextUtil.Instance ctxUtilInst) { super(config); - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; init(); } @@ -78,7 +78,7 @@ private Factory> proxyLoader(final Factory> return new Factory>() { @Override public CacheLoader create() { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { final CacheLoader loader = fact.create(); return new CacheLoaderImpl(loader); } @@ -91,14 +91,14 @@ public CacheLoaderImpl(CacheLoader loader) { @Override public V load(K k) throws CacheLoaderException { - try (Context context = ctxUtil.pushRequestContext()) { + try (Context context = ctxUtilInst.pushRequestContext()) { return loader.load(k); } } @Override public Map loadAll(Iterable itrbl) throws CacheLoaderException { - try (Context context = ctxUtil.pushRequestContext()) { + try (Context context = ctxUtilInst.pushRequestContext()) { return loader.loadAll(itrbl); } } @@ -114,7 +114,7 @@ public Map loadAll(Iterable itrbl) throws CacheLoaderExceptio return new Factory>() { @Override public CacheWriter create() { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { @SuppressWarnings("unchecked") final CacheWriter delegate = (CacheWriter) fact.create(); return new CacheWriterImpl(delegate); @@ -124,28 +124,28 @@ public CacheWriter create() { class CacheWriterImpl implements CacheWriter { @Override public void write(Cache.Entry entry) throws CacheWriterException { - try (Context context = ctxUtil.pushRequestContext()) { + try (Context context = ctxUtilInst.pushRequestContext()) { delegate.write(entry); } } @Override public void writeAll(Collection> clctn) throws CacheWriterException { - try (Context context = ctxUtil.pushRequestContext()) { + try (Context context = ctxUtilInst.pushRequestContext()) { delegate.writeAll(clctn); } } @Override public void delete(Object o) throws CacheWriterException { - try (Context context = ctxUtil.pushRequestContext()) { + try (Context context = ctxUtilInst.pushRequestContext()) { delegate.delete(o); } } @Override public void deleteAll(Collection clctn) throws CacheWriterException { - try (Context context = ctxUtil.pushRequestContext()) { + try (Context context = ctxUtilInst.pushRequestContext()) { delegate.deleteAll(clctn); } } @@ -161,6 +161,6 @@ public CacheWriterImpl(CacheWriter delegate) { }; } - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; private static final long serialVersionUID = 1L; } diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/EntryProcessorProxy.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/EntryProcessorProxy.java index 8e0942af1a6..7912570fe78 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/EntryProcessorProxy.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/contextproxy/EntryProcessorProxy.java @@ -57,17 +57,17 @@ public class EntryProcessorProxy implements EntryProcessor, Serializable { @Override public T process(MutableEntry me, Object... os) throws EntryProcessorException { - try (Context ctx = ctxUtil.pushContext()) { + try (Context ctx = ctxUtilInst.pushContext()) { return delegate.process(me, os); } } - public EntryProcessorProxy(EntryProcessor delegate, JavaEEContextUtil ctxUtil) { + public EntryProcessorProxy(EntryProcessor delegate, JavaEEContextUtil.Instance ctxUtilInst) { this.delegate = delegate; - this.ctxUtil = ctxUtil; + this.ctxUtilInst = ctxUtilInst; } private final EntryProcessor delegate; - private final JavaEEContextUtil ctxUtil; + private final JavaEEContextUtil.Instance ctxUtilInst; private static final long serialVersionUID = 1L; } From 8f24ea13ca1044c3b97fa30ae7c05b73d7973b11 Mon Sep 17 00:00:00 2001 From: lprimak Date: Sat, 28 Nov 2020 11:24:37 -0600 Subject: [PATCH 2/5] using member reference, diamond infrerence --- .../glassfish/cdi/transaction/TransactionScopedCDIUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java b/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java index 62956a9a64c..510b952ff2a 100644 --- a/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java +++ b/appserver/web/weld-integration/src/main/java/org/glassfish/cdi/transaction/TransactionScopedCDIUtil.java @@ -219,7 +219,7 @@ public BeanWrapper(Class beanClass) { catch(MultiException e) { log(e.getMessage()); } - this.ctxUtil = ctxUtil.map(util -> util.currentInvocation()); + this.ctxUtil = ctxUtil.map(JavaEEContextUtil::currentInvocation); } private void setInjectionTarget(InjectionTarget injectionTarget) { @@ -243,7 +243,7 @@ public String getName() { @Override public Set getQualifiers() { - Set qualifiers = new HashSet(); + Set qualifiers = new HashSet<>(); qualifiers.add(new DefaultAnnotationLiteral()); qualifiers.add(new AnyAnnotationLiteral()); return qualifiers; From 4993faf76c122c4ff03d025ccb0781ce71025a4a Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 30 Nov 2020 09:50:02 -0600 Subject: [PATCH 3/5] field order --- .../payara/nucleus/hazelcast/PayaraHazelcastSerializer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java index ea9f3ea450f..a7c394fdcae 100644 --- a/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java +++ b/nucleus/payara-modules/hazelcast-bootstrap/src/main/java/fish/payara/nucleus/hazelcast/PayaraHazelcastSerializer.java @@ -57,9 +57,9 @@ * @since 4.1.2.173 */ public class PayaraHazelcastSerializer implements StreamSerializer { + private static final Logger log = Logger.getLogger(PayaraHazelcastSerializer.class.getName()); private final JavaEEContextUtil ctxUtil; private final StreamSerializer delegate; - private static final Logger log = Logger.getLogger(PayaraHazelcastSerializer.class.getName()); @SuppressWarnings("unchecked") From bcde05e86caeab6c1ffc2e45b333824ba005f734 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 30 Nov 2020 10:47:57 -0600 Subject: [PATCH 4/5] removed public context API since it was such a hot-button issue --- api/payara-api/pom.xml | 1 - .../appserver/context/CDIExtension.java | 58 --------------- .../appserver/context/ContextCDIProducer.java | 72 ------------------- .../appserver/context/ContextualizerImpl.java | 4 +- .../javax.enterprise.inject.spi.Extension | 1 - .../internal/api}/ContextProducer.java | 10 +-- .../internal/api}/Contextualizer.java | 2 +- .../internal/api/JavaEEContextUtil.java | 10 ++- 8 files changed, 12 insertions(+), 146 deletions(-) delete mode 100644 appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java delete mode 100644 appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java delete mode 100644 appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension rename {api/payara-api/src/main/java/fish/payara/context => nucleus/common/internal-api/src/main/java/org/glassfish/internal/api}/ContextProducer.java (95%) rename {api/payara-api/src/main/java/fish/payara/context => nucleus/common/internal-api/src/main/java/org/glassfish/internal/api}/Contextualizer.java (99%) diff --git a/api/payara-api/pom.xml b/api/payara-api/pom.xml index 70e8287460c..d2d7c42a406 100644 --- a/api/payara-api/pom.xml +++ b/api/payara-api/pom.xml @@ -107,7 +107,6 @@ fish.payara.cdi.auth.roles, fish.payara.cdi.jsr107.impl, fish.payara.cluster, - fish.payara.context, fish.payara.jacc, fish.payara.micro.cdi, fish.payara.nucleus.requesttracing.api, diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java deleted file mode 100644 index e409a701ac5..00000000000 --- a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/CDIExtension.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) [2020] 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/master/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 fish.payara.appserver.context; - -import javax.enterprise.event.Observes; -import javax.enterprise.inject.spi.AnnotatedType; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.BeforeBeanDiscovery; -import javax.enterprise.inject.spi.Extension; - -/** - * adds context producer - * - * @author lprimak - */ -public class CDIExtension implements Extension { - void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager bm) { - AnnotatedType at = bm.createAnnotatedType(ContextCDIProducer.class); - bbd.addAnnotatedType(at, ContextCDIProducer.class.getName()); - } -} diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java deleted file mode 100644 index d83ed7c66e3..00000000000 --- a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextCDIProducer.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) [2020] 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/master/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 fish.payara.appserver.context; - -import fish.payara.context.ContextProducer; -import fish.payara.context.Contextualizer; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Produces; -import org.glassfish.internal.api.Globals; -import org.glassfish.internal.api.JavaEEContextUtil; - -/** - * CDI producer for context - * - * @author lprimak - */ -public class ContextCDIProducer { - private final ContextProducer contextproducer = Globals.getDefaultHabitat() - .getService(JavaEEContextUtil.class); - private final Contextualizer contextualizer = Globals.getDefaultHabitat() - .getService(ContextualizerImpl.class); - - - @Produces - @ApplicationScoped - Contextualizer getContextualizer() { - return contextualizer; - } - - @Produces - @ApplicationScoped - ContextProducer getContextProducer() { - return contextproducer; - } -} diff --git a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java index 9373055284c..8b1448d726f 100644 --- a/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java +++ b/appserver/web/gf-web-connector/src/main/java/fish/payara/appserver/context/ContextualizerImpl.java @@ -39,8 +39,8 @@ */ package fish.payara.appserver.context; -import fish.payara.context.ContextProducer; -import fish.payara.context.Contextualizer; +import org.glassfish.internal.api.ContextProducer; +import org.glassfish.internal.api.Contextualizer; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; diff --git a/appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension deleted file mode 100644 index cdbfb265970..00000000000 --- a/appserver/web/gf-web-connector/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension +++ /dev/null @@ -1 +0,0 @@ -fish.payara.appserver.context.CDIExtension \ No newline at end of file diff --git a/api/payara-api/src/main/java/fish/payara/context/ContextProducer.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ContextProducer.java similarity index 95% rename from api/payara-api/src/main/java/fish/payara/context/ContextProducer.java rename to nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ContextProducer.java index eeaf43aeda2..5301029144d 100644 --- a/api/payara-api/src/main/java/fish/payara/context/ContextProducer.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/ContextProducer.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.context; +package org.glassfish.internal.api; import java.io.Serializable; @@ -74,14 +74,6 @@ public interface ContextProducer { */ Instance currentInvocation() throws IllegalStateException; - /** - * - * @param componentId component id for this instance, non-null - * - * @return new instance based on componentId - */ - Instance fromComponentId(String componentId) throws IllegalArgumentException; - /** * @return Class Loader that's associated with current invocation or null if * there is no current invocation diff --git a/api/payara-api/src/main/java/fish/payara/context/Contextualizer.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/Contextualizer.java similarity index 99% rename from api/payara-api/src/main/java/fish/payara/context/Contextualizer.java rename to nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/Contextualizer.java index 084673694c5..d2497f93181 100644 --- a/api/payara-api/src/main/java/fish/payara/context/Contextualizer.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/Contextualizer.java @@ -37,7 +37,7 @@ * only if the new code is made subject to such option by the copyright * holder. */ -package fish.payara.context; +package org.glassfish.internal.api; import java.util.stream.Stream; diff --git a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java index e135174c2a3..0b3e61776f4 100644 --- a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java @@ -39,7 +39,6 @@ */ package org.glassfish.internal.api; -import fish.payara.context.ContextProducer; import org.jvnet.hk2.annotations.Contract; /** @@ -51,7 +50,14 @@ public interface JavaEEContextUtil extends ContextProducer { @Override Instance empty(); @Override Instance currentInvocation() throws IllegalStateException; - @Override Instance fromComponentId(String componentId) throws IllegalArgumentException; + + /** + * + * @param componentId component id for this instance, non-null + * + * @return new instance based on componentId + */ + ContextProducer.Instance fromComponentId(String componentId) throws IllegalArgumentException; interface Instance extends ContextProducer.Instance { @Override Context pushContext(); From 034db30aa16ac8d704c347a81fbd214e312b4c59 Mon Sep 17 00:00:00 2001 From: lprimak Date: Mon, 30 Nov 2020 11:16:14 -0600 Subject: [PATCH 5/5] fixed compile error --- .../main/java/org/glassfish/internal/api/JavaEEContextUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java index 0b3e61776f4..c40d47abf4c 100644 --- a/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java +++ b/nucleus/common/internal-api/src/main/java/org/glassfish/internal/api/JavaEEContextUtil.java @@ -57,7 +57,7 @@ public interface JavaEEContextUtil extends ContextProducer { * * @return new instance based on componentId */ - ContextProducer.Instance fromComponentId(String componentId) throws IllegalArgumentException; + Instance fromComponentId(String componentId) throws IllegalArgumentException; interface Instance extends ContextProducer.Instance { @Override Context pushContext();