tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject [2/2] tomee git commit: TOMEE-2055 ensure @AroundConstruct doesnt prevent to have an instance
Date Thu, 08 Jun 2017 13:32:09 GMT
TOMEE-2055 ensure @AroundConstruct doesnt prevent to have an instance


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/4a09afb5
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/4a09afb5
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/4a09afb5

Branch: refs/heads/master
Commit: 4a09afb5bdc240dfce8056196592b6448ab5c538
Parents: d592cc6
Author: rmannibucau <rmannibucau@apache.org>
Authored: Thu Jun 8 15:31:53 2017 +0200
Committer: rmannibucau <rmannibucau@apache.org>
Committed: Thu Jun 8 15:31:53 2017 +0200

----------------------------------------------------------------------
 .../java/org/apache/openejb/BeanContext.java    | 51 ++++++++--
 .../java/org/apache/openejb/cdi/CdiEjbBean.java |  6 +-
 .../openejb/cdi/AroundConstructCdiTest.java     | 98 ++++++++++++++++++++
 3 files changed, 146 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/4a09afb5/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java b/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
index a33fb5f..5c72841 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java
@@ -49,6 +49,7 @@ import org.apache.webbeans.component.CdiInterceptorBean;
 import org.apache.webbeans.component.InjectionTargetBean;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.context.creational.CreationalContextImpl;
+import org.apache.webbeans.context.creational.DependentCreationalContext;
 import org.apache.webbeans.inject.OWBInjector;
 import org.apache.webbeans.intercept.DecoratorHandler;
 import org.apache.webbeans.intercept.InterceptorResolutionService;
@@ -102,6 +103,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Future;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
 
 @SuppressWarnings("unchecked")
 public class BeanContext extends DeploymentContext {
@@ -111,6 +113,17 @@ public class BeanContext extends DeploymentContext {
     public static final String USER_INTERCEPTOR_KEY = "org.apache.openejb.default.system.interceptors";
     public static final String USER_INTERCEPTOR_SEPARATOR = ",| |;";
 
+    private static final Field DEPENDENTS_OBJECTS;
+
+    static {
+        try {
+            DEPENDENTS_OBJECTS = CreationalContextImpl.class.getDeclaredField("dependentObjects");
+            DEPENDENTS_OBJECTS.setAccessible(true);
+        } catch (final NoSuchFieldException e) {
+            throw new IllegalStateException("Invalid OpenWebBeans version", e);
+        }
+    }
+
     private ConstructorInjectionBean<Object> constructorInjectionBean;
     private final boolean passivable;
 
@@ -1634,6 +1647,7 @@ public class BeanContext extends DeploymentContext {
                 interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
             }
 
+            final Collection<DependentCreationalContext<?>> createdDependents
= getDependents(creationalContext);
             for (final InterceptorData interceptorData : this.getInstanceScopedInterceptors())
{
                 if (interceptorData.getInterceptorClass().equals(beanClass)) {
                     continue;
@@ -1643,17 +1657,30 @@ public class BeanContext extends DeploymentContext {
 
                 final Object iInstance;
                 if (webBeansContext != null) {
-                    ConstructorInjectionBean interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
-                    if (interceptorConstructor == null) {
-                        synchronized (this) {
-                            interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
-                            if (interceptorConstructor == null) {
-                                interceptorConstructor = new ConstructorInjectionBean(webBeansContext,
clazz, webBeansContext.getAnnotatedElementFactory().newAnnotatedType(clazz));
-                                interceptorData.set(ConstructorInjectionBean.class, interceptorConstructor);
+                    Object preInstantiated = null;
+                    if (createdDependents != null) {
+                        for (final DependentCreationalContext<?> dcc : createdDependents)
{
+                            if (clazz.isInstance(dcc.getInstance())) { // is that enough?
do we have more to match?
+                                preInstantiated = dcc.getInstance();
+                                break;
                             }
                         }
                     }
-                    iInstance = interceptorConstructor.create(creationalContext);
+                    if (preInstantiated != null) {
+                        iInstance = preInstantiated;
+                    } else {
+                        ConstructorInjectionBean interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
+                        if (interceptorConstructor == null) {
+                            synchronized (this) {
+                                interceptorConstructor = interceptorData.get(ConstructorInjectionBean.class);
+                                if (interceptorConstructor == null) {
+                                    interceptorConstructor = new ConstructorInjectionBean(webBeansContext,
clazz, webBeansContext.getAnnotatedElementFactory().newAnnotatedType(clazz));
+                                    interceptorData.set(ConstructorInjectionBean.class, interceptorConstructor);
+                                }
+                            }
+                        }
+                        iInstance = interceptorConstructor.create(creationalContext);
+                    }
                 } else {
                     iInstance = clazz.newInstance();
                 }
@@ -1743,6 +1770,14 @@ public class BeanContext extends DeploymentContext {
         }
     }
 
+    private Collection<DependentCreationalContext<?>> getDependents(final CreationalContext<Object>
creationalContext) {
+        try {
+            return Collection.class.cast(DEPENDENTS_OBJECTS.get(creationalContext));
+        } catch (final Exception e) {
+            return emptyList();
+        }
+    }
+
     private ConstructorInjectionBean<Object> createConstructorInjectionBean(final WebBeansContext
webBeansContext) {
         if (constructorInjectionBean != null) {
             return constructorInjectionBean;

http://git-wip-us.apache.org/repos/asf/tomee/blob/4a09afb5/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java
index 30d381e..feeb984 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java
@@ -522,7 +522,11 @@ public class CdiEjbBean<T> extends BaseEjbBean<T> implements
InterceptedMarker,
         public T createNewPojo(final CreationalContext<T> creationalContext) {
             final CreationalContextImpl<T> ccImpl = CreationalContextImpl.class.cast(creationalContext);
             // super.produce(cc) will not work since we need the unproxied instance - decorator
case
-            return (T) super.produce(super.createInterceptorInstances(ccImpl), ccImpl);
+            final T produce = super.produce(super.createInterceptorInstances(ccImpl), ccImpl);
+            if (produce == null) { // user didnt call ic.proceed() in @AroundConstruct
+                return super.newInstance(ccImpl);
+            }
+            return (T) produce;
         }
 
         private static boolean isDynamicBean(final Bean<?> bean) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/4a09afb5/container/openejb-core/src/test/java/org/apache/openejb/cdi/AroundConstructCdiTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/cdi/AroundConstructCdiTest.java
b/container/openejb-core/src/test/java/org/apache/openejb/cdi/AroundConstructCdiTest.java
index e44cf01..b7d5fed 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/cdi/AroundConstructCdiTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/cdi/AroundConstructCdiTest.java
@@ -1,4 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.apache.openejb.cdi;
 
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Classes;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.Singleton;
+import javax.inject.Inject;
+import javax.interceptor.AroundConstruct;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InterceptorBinding;
+import javax.interceptor.InvocationContext;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.Assert.assertEquals;
+
+// ensure @AroundConstruct doesnt fail and prevent to use EJB in its both flavors/signatures
+@RunWith(ApplicationComposer.class)
+@Classes(cdi = true, innerClassesAsBean = true, cdiInterceptors = {AroundConstructCdiTest.AC1.class,
AroundConstructCdiTest.AC2.class})
 public class AroundConstructCdiTest {
+    @Inject
+    private Bean bean;
+
+    @Test
+    public void run() {
+        assertEquals("truetrueget", bean.get());
+    }
+
+    @B1 @B2
+    @Singleton
+    public static class Bean {
+        public String get() {
+            return "get";
+        }
+    }
+
+    @B1
+    @Interceptor
+    public static class AC1 {
+        private boolean constructured = false;
+
+        @AroundConstruct
+        public Object ac(InvocationContext ic) throws Exception {
+            constructured = true;
+            return ic.proceed();
+        }
+
+        @AroundInvoke
+        public Object ai(final InvocationContext ic) throws Exception {
+            return constructured + ic.proceed().toString();
+        }
+    }
+
+    @InterceptorBinding
+    @Target(TYPE)
+    @Retention(RUNTIME)
+    public @interface B1 {
+    }
+
+    @B2
+    @Interceptor
+    public static class AC2 {
+        private boolean constructured = false;
+
+        @AroundConstruct
+        public void ac(final InvocationContext ic) {
+            constructured = true;
+        }
+
+        @AroundInvoke
+        public Object ai(final InvocationContext ic) throws Exception {
+            return constructured + ic.proceed().toString();
+        }
+    }
+
+    @InterceptorBinding
+    @Target(TYPE)
+    @Retention(RUNTIME)
+    public @interface B2 {
+    }
 }


Mime
View raw message