Repository: tomee Updated Branches: refs/heads/develop a4fd70746 -> af02e201e
rework cdi bean discovery - optim + alignment on the spec Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/af02e201 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/af02e201 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/af02e201 Branch: refs/heads/develop Commit: af02e201e205035be3a70fd6ac7b67be311b5544 Parents: a4fd707 Author: Romain Manni-Bucau <[email protected]> Authored: Fri Jan 2 15:36:32 2015 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Fri Jan 2 15:36:32 2015 +0100 ---------------------------------------------------------------------- .../java/org/apache/openejb/cdi/CdiScanner.java | 9 +- .../openejb/config/AnnotationDeployer.java | 134 +++++++++++-------- tck/cdi-embedded/src/test/resources/failing.xml | 2 +- 3 files changed, 88 insertions(+), 57 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/af02e201/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java index 04a7864..27e2ac0 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiScanner.java @@ -35,11 +35,13 @@ import org.apache.openejb.util.Logger; import org.apache.openejb.util.classloader.ClassLoaderComparator; import org.apache.openejb.util.classloader.DefaultClassLoaderComparator; import org.apache.webbeans.config.WebBeansContext; +import org.apache.webbeans.container.BeanManagerImpl; import org.apache.webbeans.intercept.InterceptorsManager; import org.apache.webbeans.spi.BDABeansXmlScanner; import org.apache.webbeans.spi.BeanArchiveService; import org.apache.webbeans.spi.ScannerService; +import javax.decorator.Decorator; import java.lang.annotation.Annotation; import java.net.MalformedURLException; import java.net.URL; @@ -281,8 +283,11 @@ public class CdiScanner implements ScannerService { try { for (final Annotation a : clazz.getAnnotations()) { final Class<? extends Annotation> annotationType = a.annotationType(); - if (webBeansContext.getBeanManagerImpl().isScope(annotationType) - || webBeansContext.getBeanManagerImpl().isStereotype(annotationType)) { + final BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl(); + if (beanManager.isScope(annotationType) + || beanManager.isStereotype(annotationType) + || beanManager.isInterceptorBinding(annotationType) + || Decorator.class == a.annotationType()) { return true; } } http://git-wip-us.apache.org/repos/asf/tomee/blob/af02e201/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java b/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java index 5430dc9..d4e5269 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java @@ -25,6 +25,7 @@ import org.apache.openejb.api.RemoteClient; import org.apache.openejb.cdi.CdiBeanInfo; import org.apache.openejb.config.rules.CheckClasses; import org.apache.openejb.core.EmptyResourcesClassLoader; +import org.apache.openejb.core.ParentClassLoaderFinder; import org.apache.openejb.core.TempClassLoader; import org.apache.openejb.core.webservices.JaxWsUtils; import org.apache.openejb.dyni.DynamicSubclass; @@ -146,6 +147,7 @@ import javax.annotation.security.RolesAllowed; import javax.annotation.security.RunAs; import javax.annotation.sql.DataSourceDefinition; import javax.annotation.sql.DataSourceDefinitions; +import javax.decorator.Delegate; import javax.ejb.AccessTimeout; import javax.ejb.ActivationConfigProperty; import javax.ejb.AfterBegin; @@ -184,7 +186,13 @@ import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.ejb.TransactionManagement; import javax.ejb.TransactionManagementType; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.ConversationScoped; +import javax.enterprise.context.Dependent; import javax.enterprise.context.NormalScope; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.context.SessionScoped; +import javax.enterprise.inject.Model; import javax.enterprise.inject.Produces; import javax.enterprise.inject.Stereotype; import javax.enterprise.inject.spi.DefinitionException; @@ -1653,6 +1661,9 @@ public class AnnotationDeployer implements DynamicDeployer { final WebappAggregatedArchive aggregatedArchive = (WebappAggregatedArchive) archive; final Map<URL, List<String>> map = aggregatedArchive.getClassesMap(); + Collection<Class<?>> discoveredBeans = null; + List<Class<? extends Extension>> extensions = null; + for (final Map.Entry<URL, List<String>> entry : map.entrySet()) { final URL key = entry.getKey(); final URL beansXml = hasBeansXml(key); @@ -1660,74 +1671,89 @@ public class AnnotationDeployer implements DynamicDeployer { if (beansXml != null) { classes.put(beansXml, value); } else if (!value.isEmpty()) { - final Set<String> potentialClasses = new HashSet<>(); - - final Set<Class<?>> newMarkers = new HashSet<>(finder.findAnnotatedClasses(Stereotype.class)); - newMarkers.addAll(finder.findAnnotatedClasses(NormalScope.class)); - newMarkers.addAll(finder.findAnnotatedClasses(Scope.class)); - - do { - final Set<Class<?>> loopMarkers = new HashSet<>(newMarkers); - newMarkers.clear(); - for (final Class<?> marker : loopMarkers) { - potentialClasses.add(marker.getName()); - - final List<Class<?>> found = finder.findAnnotatedClasses(Class.class.cast(marker)); - for (final Class<?> c : found) { - if (c.isAnnotation()) { - newMarkers.add(c); - } - if (value.contains(c.getName())) { - potentialClasses.add(c.getName()); - } + final Set<String> fastValue = new HashSet<>(value); + if (discoveredBeans == null) { // lazy init for apps not using it, it slows down the app boot and that should be useless + discoveredBeans = new HashSet<>(); + + final Set<Class<? extends Annotation>> containerAnnot = new HashSet<>(); + containerAnnot.add(Stereotype.class); + containerAnnot.add(NormalScope.class); + containerAnnot.add(Scope.class); + containerAnnot.add(Dependent.class); + containerAnnot.add(javax.inject.Singleton.class); + containerAnnot.add(ApplicationScoped.class); + containerAnnot.add(ConversationScoped.class); + containerAnnot.add(RequestScoped.class); + containerAnnot.add(SessionScoped.class); + containerAnnot.add(Model.class); + containerAnnot.add(javax.interceptor.InterceptorBinding.class); + containerAnnot.add(Singleton.class); + containerAnnot.add(Stateless.class); + containerAnnot.add(Stateful.class); + containerAnnot.add(MessageDriven.class); + final ClassLoader classLoader = ParentClassLoaderFinder.Helper.get(); + try { + for (final String name : asList("javax.faces.flow.FlowScoped", "javax.faces.view.ViewScoped")) { + containerAnnot.add((Class<? extends Annotation>) classLoader.loadClass(name)); } + } catch (final Throwable e) { + // no-op } - } while (!newMarkers.isEmpty()); - - newMarkers.clear(); - newMarkers.add(Stateful.class); - newMarkers.add(Singleton.class); - newMarkers.add(Stateless.class); - newMarkers.add(MessageDriven.class); - - boolean ejb = false; - for (final Class<?> marker : newMarkers) { - final List<Class<?>> found = finder.findAnnotatedClasses(Class.class.cast(marker)); - for (final Class<?> c : found) { - if (value.contains(c.getName())) { - potentialClasses.add(c.getName()); - ejb = true; - } + + final Set<Class<?>> newMarkers = new HashSet<>(); + for (final Class<? extends Annotation> a : containerAnnot) { + newMarkers.addAll(finder.findAnnotatedClasses(a)); } - } - if (ejb) { - final List<Class<? extends Extension>> extensions = finder.findImplementations(Extension.class); - boolean skip = false; - for (final Class<?> c : extensions) { - if (value.contains(c.getName())) { - // legacy mode, we should check META-INF/services/... but this mode + having an Extension should be enough - skip = true; - continue; + + do { + final Set<Class<?>> loopMarkers = new HashSet<>(newMarkers); + newMarkers.clear(); + for (final Class<?> marker : loopMarkers) { + discoveredBeans.add(marker); + + final List<Class<?>> found = finder.findAnnotatedClasses(Class.class.cast(marker)); + for (final Class<?> c : found) { + if (c.isAnnotation()) { + newMarkers.add(c); + } + discoveredBeans.add(c); + } } + } while (!newMarkers.isEmpty()); + + for (final Field field : finder.findAnnotatedFields(Delegate.class)) { // should be done for constructors but too slow? + discoveredBeans.add(field.getDeclaringClass()); } - if (skip) { + + extensions = finder.findImplementations(Extension.class); + } + + boolean skip = false; + for (final Class<?> c : extensions) { + if (fastValue.contains(c.getName())) { + // legacy mode, we should check META-INF/services/... but this mode + having an Extension should be enough + skip = true; continue; } } - - if (potentialClasses.isEmpty()) { + if (skip) { continue; } - // intersection - final List<String> diff = new ArrayList<>(entry.getValue()); - diff.removeAll(potentialClasses); + final Set<String> beans = new HashSet<>(); + for (final Class<?> c : discoveredBeans) { + final String name = c.getName(); + if (fastValue.contains(name)) { + beans.add(name); + } + } - final List<String> copy = new ArrayList<>(entry.getValue()); - copy.removeAll(diff); + if (beans.isEmpty()) { + continue; + } // just keep the potential ones to not load all classes during boot - notManaged.put(entry.getKey(), copy); + notManaged.put(entry.getKey(), new ArrayList<String>(beans)); } } } http://git-wip-us.apache.org/repos/asf/tomee/blob/af02e201/tck/cdi-embedded/src/test/resources/failing.xml ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/src/test/resources/failing.xml b/tck/cdi-embedded/src/test/resources/failing.xml index bad9ab4..5ca42d2 100644 --- a/tck/cdi-embedded/src/test/resources/failing.xml +++ b/tck/cdi-embedded/src/test/resources/failing.xml @@ -26,7 +26,7 @@ -Dopenejb.deploymentId.format={appId}/{ejbJarId}/{ejbName} --> <classes> - <class name="org.jboss.cdi.tck.tests.context.conversation.LongRunningConversationPropagatedByFacesContextTest" /> + <class name="org.jboss.cdi.tck.tests.implementation.enterprise.newBean.NewEnterpriseBeanTest" /> </classes> </test> </suite>
