You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2017/06/08 13:32:08 UTC

[1/2] tomee git commit: TOMEE-2055 ensure @AroundConstruct doesnt prevent to have an instance

Repository: tomee
Updated Branches:
  refs/heads/master 68aef6ffe -> 4a09afb5b


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/d592cc63
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d592cc63
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d592cc63

Branch: refs/heads/master
Commit: d592cc63b86528d6aeb5666319281fe50a09895e
Parents: 68aef6f
Author: rmannibucau <rm...@apache.org>
Authored: Thu Jun 8 15:31:45 2017 +0200
Committer: rmannibucau <rm...@apache.org>
Committed: Thu Jun 8 15:31:45 2017 +0200

----------------------------------------------------------------------
 .../openejb/cdi/AroundConstructCdiTest.java     |  4 +
 .../tomee/embedded/UTTransactionalTest.java     | 83 ++++++++++++++++++++
 2 files changed, 87 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/d592cc63/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
new file mode 100644
index 0000000..e44cf01
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/cdi/AroundConstructCdiTest.java
@@ -0,0 +1,4 @@
+package org.apache.openejb.cdi;
+
+public class AroundConstructCdiTest {
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/d592cc63/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/UTTransactionalTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/UTTransactionalTest.java b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/UTTransactionalTest.java
new file mode 100644
index 0000000..886407b
--- /dev/null
+++ b/tomee/tomee-embedded/src/test/java/org/apache/tomee/embedded/UTTransactionalTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.tomee.embedded;
+
+import org.apache.openejb.loader.IO;
+import org.apache.openejb.util.NetworkUtil;
+import org.junit.Test;
+
+import javax.annotation.Resource;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.transaction.NotSupportedException;
+import javax.transaction.SystemException;
+import javax.transaction.Transactional;
+import javax.transaction.UserTransaction;
+import java.io.IOException;
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class UTTransactionalTest {
+    @Test
+    public void run() throws IOException {
+        try (final Container c = new Container(new Configuration()
+                .http(NetworkUtil.getNextAvailablePort())
+                //.property("openejb.container.additional.exclude", "org.apache.tomee.embedded.")
+                .property("openejb.additional.include", "tomee-"))
+                .deployClasspathAsWebApp()) {
+            assertEquals("IllegalStateException", IO.slurp(new URL("http://localhost:" + c.getConfiguration().getHttpPort() + "/UTTransactionalTest")));
+        }
+    }
+
+    @ApplicationScoped
+    @Transactional
+    public static class Bean {
+        @Resource
+        private UserTransaction ut;
+
+        public void noUt() {
+            try {
+                ut.begin();
+            } catch (final NotSupportedException | SystemException e) {
+                fail();
+            }
+        }
+    }
+
+    @WebServlet(urlPatterns = "/UTTransactionalTest", loadOnStartup = 1)
+    public static class Endpoint extends HttpServlet {
+        @Inject
+        private Bean bean;
+
+        @Override
+        protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+            try {
+                bean.noUt();
+                resp.getWriter().write("ok");
+            } catch (final IllegalStateException ise) {
+                resp.getWriter().write("IllegalStateException");
+            }
+        }
+    }
+}


[2/2] tomee git commit: TOMEE-2055 ensure @AroundConstruct doesnt prevent to have an instance

Posted by rm...@apache.org.
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 <rm...@apache.org>
Authored: Thu Jun 8 15:31:53 2017 +0200
Committer: rmannibucau <rm...@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 {
+    }
 }