Author: rmannibucau
Date: Sun Aug 24 16:39:26 2014
New Revision: 1620149
URL: http://svn.apache.org/r1620149
Log:
TOMEE-1332 @Startup on cdi normal scoped beans when context exists at boot time
Added:
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StartupOnCdiBeanTest.java
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/BeansInfo.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
tomee/tomee/trunk/container/openejb-jee/src/main/java/org/apache/openejb/jee/Beans.java
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/BeansInfo.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/BeansInfo.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/BeansInfo.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/BeansInfo.java
Sun Aug 24 16:39:26 2014
@@ -19,23 +19,27 @@ package org.apache.openejb.assembler.cla
import java.net.URI;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
/**
* @version $Rev$ $Date$
*/
public class BeansInfo extends InfoObject {
- public final List<String> interceptors = new ArrayList<String>();
- public final List<String> decorators = new ArrayList<String>();
- public final List<String> alternativeClasses = new ArrayList<String>();
- public final List<String> alternativeStereotypes = new ArrayList<String>();
-
- public final List<String> duplicatedInterceptors = new ArrayList<String>();
- public final List<String> duplicatedDecorators = new ArrayList<String>();
- public final List<String> duplicatedAlternativeClasses = new
ArrayList<String>();
- public final List<String> duplicatedAlternativeStereotypes = new
ArrayList<String>();
+ public final List<String> interceptors = new ArrayList<>();
+ public final List<String> decorators = new ArrayList<>();
+ public final List<String> alternativeClasses = new ArrayList<>();
+ public final List<String> alternativeStereotypes = new ArrayList<>();
+
+ public final List<String> duplicatedInterceptors = new ArrayList<>();
+ public final List<String> duplicatedDecorators = new ArrayList<>();
+ public final List<String> duplicatedAlternativeClasses = new ArrayList<>();
+ public final List<String> duplicatedAlternativeStereotypes = new
ArrayList<>();
+
+ public final Set<String> startupClasses = new HashSet<>();
public String version = "1.1";
public String discoveryMode;
@@ -48,7 +52,7 @@ public class BeansInfo extends InfoObjec
}
public static class BDAInfo extends InfoObject {
- public final List<String> managedClasses = new ArrayList<String>();
+ public final List<String> managedClasses = new ArrayList<>();
public String discoveryMode;
public URI uri;
}
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java
Sun Aug 24 16:39:26 2014
@@ -62,8 +62,8 @@ public class CdiScanner implements Scann
RequiredInterceptor.class, RequiredNewInterceptor.class,
SupportsInterceptor.class
};
- // TODO add all annotated class
private final Set<Class<?>> classes = new HashSet<>();
+ private final Set<Class<?>> startupClasses = new HashSet<>();
private WebBeansContext webBeansContext;
@@ -220,11 +220,17 @@ public class CdiScanner implements Scann
if (scanModeAnnotated) {
if (isBean(clazz)) {
classes.add(clazz);
+ if (beans.startupClasses.contains(name)) {
+ startupClasses.add(clazz);
+ }
}
} else {
final ClassLoader loader = clazz.getClassLoader();
if (!filterByClassLoader ||
comparator.isSame(loader) || loader.equals(scl) && isNotEarWebApp) {
classes.add(clazz);
+ if (beans.startupClasses.contains(name)) {
+ startupClasses.add(clazz);
+ }
}
}
}
@@ -324,4 +330,8 @@ public class CdiScanner implements Scann
public void release() {
classes.clear();
}
+
+ public Set<Class<?>> getStartupClasses() {
+ return startupClasses;
+ }
}
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
Sun Aug 24 16:39:26 2014
@@ -43,11 +43,15 @@ import org.apache.webbeans.util.WebBeans
import org.apache.webbeans.util.WebBeansUtil;
import javax.el.ELResolver;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.jsp.JspApplicationContext;
import javax.servlet.jsp.JspFactory;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -153,6 +157,7 @@ public class OpenEJBLifecycle implements
injectionService.setAppContext(stuff.getAppContext());
//Deploy the beans
+ CdiScanner cdiScanner = null;
try {
//Load Extensions
webBeansContext.getExtensionLoader().loadExtensionServices(Thread.currentThread().getContextClassLoader());
// init in OpenEJBLifecycle
@@ -164,12 +169,12 @@ public class OpenEJBLifecycle implements
logger.debug("Scanning classpaths for beans artifacts.");
if (scannerService instanceof CdiScanner) {
- final CdiScanner service = (CdiScanner) scannerService;
- service.setContext(webBeansContext);
- service.init(startupObject);
+ cdiScanner = CdiScanner.class.cast(scannerService);
+ cdiScanner.setContext(webBeansContext);
+ cdiScanner.init(startupObject);
} else {
- final CdiScanner cdiScanner = new CdiScanner();
- ((CdiScanner) scannerService).setContext(webBeansContext);
+ cdiScanner = new CdiScanner();
+ cdiScanner.setContext(webBeansContext);
cdiScanner.init(startupObject);
}
@@ -177,7 +182,7 @@ public class OpenEJBLifecycle implements
this.scannerService.scan();
// just to let us write custom CDI Extension using our
internals easily
-
CURRENT_APP_INFO.set(StartupObject.class.cast(startupObject).getAppInfo());
+ CURRENT_APP_INFO.set(stuff.getAppInfo());
//Deploy bean from XML. Also configures deployments,
interceptors, decorators.
deployer.deploy(scannerService);
@@ -188,12 +193,15 @@ public class OpenEJBLifecycle implements
CURRENT_APP_INFO.remove();
}
+ final Collection<Class<?>> ejbs = new
ArrayList<>(stuff.getBeanContexts().size());
for (final BeanContext bc : stuff.getBeanContexts()) {
final CdiEjbBean cdiEjbBean = bc.get(CdiEjbBean.class);
if (cdiEjbBean == null) {
continue;
}
+ ejbs.add(bc.getManagedClass());
+
if (AbstractProducer.class.isInstance(cdiEjbBean)) {
AbstractProducer.class.cast(cdiEjbBean).defineInterceptorStack(cdiEjbBean,
cdiEjbBean.getAnnotatedType(), cdiEjbBean.getWebBeansContext());
}
@@ -206,6 +214,13 @@ public class OpenEJBLifecycle implements
if (beanManager instanceof WebappBeanManager) {
((WebappBeanManager) beanManager).afterStart();
}
+
+ for (final Class<?> clazz : cdiScanner.getStartupClasses()) {
+ if (ejbs.contains(clazz)) {
+ continue;
+ }
+ starts(beanManager, clazz);
+ }
} finally {
Thread.currentThread().setContextClassLoader(oldCl);
@@ -216,6 +231,17 @@ public class OpenEJBLifecycle implements
logger.info("OpenWebBeans Container has started, it took {0} ms.",
Long.toString(System.currentTimeMillis() - begin));
}
+ private void starts(final BeanManager beanManager, final Class<?> clazz) {
+ final Bean<?> bean = beanManager.resolve(beanManager.getBeans(clazz));
+ if (!beanManager.isNormalScope(bean.getScope())) {
+ throw new IllegalStateException("Only normal scoped beans can use
@Startup - likely @ApplicationScoped");
+ }
+
+ final CreationalContext<Object> creationalContext =
beanManager.createCreationalContext(null);
+ beanManager.getReference(bean, clazz, creationalContext).toString();
+ // don't release now, will be done by the context - why we restrict it
to normal scoped beans
+ }
+
@Override
public void stopApplication(final Object endObject) {
logger.debug("OpenWebBeans Container is stopping.");
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
Sun Aug 24 16:39:26 2014
@@ -1311,6 +1311,14 @@ public class AnnotationDeployer implemen
final org.apache.openejb.jee.ManagedBean managedBean = new
CompManagedBean(name, BeanContext.Comp.class);
managedBean.setTransactionType(TransactionType.BEAN);
ejbModule.getEjbJar().addEnterpriseBean(managedBean);
+
+ if
("true".equals(SystemInstance.get().getProperty("openejb.cdi.support.@Startup",
"true"))) {
+ final List<Annotated<Class<?>>> forceStart =
finder.findMetaAnnotatedClasses(Startup.class);
+ final List<String> startupBeans =
beans.getStartupBeans();
+ for (final Annotated<Class<?>> clazz : forceStart) {
+ startupBeans.add(clazz.get().getName());
+ }
+ }
} else {
managedClasses = new HashMap<>();
}
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
Sun Aug 24 16:39:26 2014
@@ -263,6 +263,8 @@ public class EjbJarInfoBuilder {
ejbJar.beans.duplicatedInterceptors.addAll(beans.getDuplicatedInterceptors());
ejbJar.beans.duplicatedDecorators.addAll(beans.getDuplicatedDecorators());
+ ejbJar.beans.startupClasses.addAll(beans.getStartupBeans());
+
final Map<URL, String> discoveryModeByUrl = new HashMap<>();
if (CompositeBeans.class.isInstance(beans)) {
discoveryModeByUrl.putAll(CompositeBeans.class.cast(beans).getDiscoveryByUrl());
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
Sun Aug 24 16:39:26 2014
@@ -88,6 +88,7 @@ import javax.enterprise.context.Conversa
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.spi.Extension;
+import javax.inject.Inject;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.io.File;
@@ -332,7 +333,12 @@ public final class ApplicationComposers
ejbDeployment.setDeploymentId(testClass.getName());
final EjbModule ejbModule = new EjbModule(ejbJar, openejbJar);
- ejbModule.setFinder(new FinderFactory.OpenEJBAnnotationFinder(new
ClassesArchive(ancestors(testClass))));
+ final FinderFactory.OpenEJBAnnotationFinder finder = new
FinderFactory.OpenEJBAnnotationFinder(new ClassesArchive(ancestors(testClass)));
+ ejbModule.setFinder(finder);
+ if (finder.findMetaAnnotatedFields(Inject.class).size()
+ + finder.findMetaAnnotatedMethods(Inject.class).size() >
0) { // activate cdi to avoid WARNINGs
+ ejbModule.setBeans(new Beans());
+ }
appModule.getEjbModules().add(ejbModule);
}
Added:
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StartupOnCdiBeanTest.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StartupOnCdiBeanTest.java?rev=1620149&view=auto
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StartupOnCdiBeanTest.java
(added)
+++
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StartupOnCdiBeanTest.java
Sun Aug 24 16:39:26 2014
@@ -0,0 +1,90 @@
+/**
+ * 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.jee.Beans;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.Startup;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(ApplicationComposer.class)
+public class StartupOnCdiBeanTest {
+ @Module
+ public Beans beans() {
+ return new Beans()
+ .managedClass(InitMeASAP.class.getName())
+ .managedClass(InitMeLater.class.getName());
+ }
+
+ @Inject
+ private BeanManager bm;
+
+ @Test
+ public void run() throws InterruptedException {
+ value = "too late";
+ final InitMeASAP instance =
InitMeASAP.class.cast(bm.getReference(bm.resolve(bm.getBeans(InitMeASAP.class)),
InitMeASAP.class, bm.createCreationalContext(null)));
+ final InitMeLater lazy =
InitMeLater.class.cast(bm.getReference(bm.resolve(bm.getBeans(InitMeLater.class)),
InitMeLater.class, bm.createCreationalContext(null)));
+ assertEquals("boot", instance.getInit());
+ assertEquals("too late", lazy.getInit());
+ }
+
+ public static String value = "boot";
+
+ @Startup
+ @ApplicationScoped
+ public static class InitMeASAP {
+ private String init;
+
+ @PostConstruct
+ public void setTrue() {
+ init = value;
+ }
+
+ public String getInit() {
+ return init;
+ }
+ }
+
+ @ApplicationScoped
+ public static class InitMeLater {
+ private String init;
+
+ @PostConstruct
+ public void setTrue() {
+ init = value;
+ }
+
+ @PreDestroy
+ public void resetForDebug() {
+ init = value;
+ }
+
+ public String getInit() {
+ return init;
+ }
+ }
+}
Modified:
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
(original)
+++
tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/transactional/TransactionalTest.java
Sun Aug 24 16:39:26 2014
@@ -110,7 +110,6 @@ public class TransactionalTest {
@Test
public void dontRollbackException() throws Exception {
final AtomicInteger status = new AtomicInteger();
- final TransactionManager transactionManager =
OpenEJB.getTransactionManager();
try {
bean.anotherException(status);
fail();
@@ -134,9 +133,7 @@ public class TransactionalTest {
assertHasTx();
try {
ut.begin();
- } catch (final NotSupportedException e) {
- fail();
- } catch (final SystemException e) {
+ } catch (final NotSupportedException | SystemException e) {
fail();
}
}
@@ -184,9 +181,7 @@ public class TransactionalTest {
status.set(state);
}
});
- } catch (final RollbackException e) {
- fail();
- } catch (final SystemException e) {
+ } catch (final RollbackException | SystemException e) {
fail();
}
throw new AnotherException();
Modified:
tomee/tomee/trunk/container/openejb-jee/src/main/java/org/apache/openejb/jee/Beans.java
URL:
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-jee/src/main/java/org/apache/openejb/jee/Beans.java?rev=1620149&r1=1620148&r2=1620149&view=diff
==============================================================================
---
tomee/tomee/trunk/container/openejb-jee/src/main/java/org/apache/openejb/jee/Beans.java
(original)
+++
tomee/tomee/trunk/container/openejb-jee/src/main/java/org/apache/openejb/jee/Beans.java
Sun Aug 24 16:39:26 2014
@@ -69,6 +69,9 @@ public class Beans {
protected List<String> duplicatedDecorators;
@XmlTransient
+ protected List<String> startupBeans;
+
+ @XmlTransient
protected Alternatives duplicatedAlternatives;
@XmlTransient
@@ -121,6 +124,15 @@ public class Beans {
this.beanDiscoveryMode = beanDiscoveryMode;
}
+ /**
+ * only for ApplicationComposer
+ * @param clazz the class to add
+ */
+ public Beans managedClass(final String clazz) {
+ addManagedClass(null, clazz);
+ return this;
+ }
+
public void addManagedClass(final URL url, final String clazz) {
List<String> list = managedClasses.get(url);
if (list == null) {
@@ -366,6 +378,13 @@ public class Beans {
return duplicatedAlternatives;
}
+ public List<String> getStartupBeans() {
+ if (startupBeans == null) {
+ startupBeans = new LinkedList<>();
+ }
+ return startupBeans;
+ }
+
public void removeDuplicates() {
removeDuplicates(getAlternativeClasses());
removeDuplicates(getAlternativeStereotypes());