You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by rm...@apache.org on 2020/12/26 17:37:25 UTC
[openwebbeans] branch master updated: [OWB-1361] startup time
improvements: enable to skip our noclassdeffound checks - in well known
cases,
enable to skip some cdi validations - once deployment is validated it helps,
skip anonymous and private classes earlier in the process,
enable to skip PAT event when there is no observer for it (todo: same for
PIP)
This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 42524ee [OWB-1361] startup time improvements: enable to skip our noclassdeffound checks - in well known cases, enable to skip some cdi validations - once deployment is validated it helps, skip anonymous and private classes earlier in the process, enable to skip PAT event when there is no observer for it (todo: same for PIP)
42524ee is described below
commit 42524ee28e0fc2ed63ed9edb99c31edd9aca2674
Author: Romain Manni-Bucau <rm...@gmail.com>
AuthorDate: Sat Dec 26 18:37:19 2020 +0100
[OWB-1361] startup time improvements: enable to skip our noclassdeffound checks - in well known cases, enable to skip some cdi validations - once deployment is validated it helps, skip anonymous and private classes earlier in the process, enable to skip PAT event when there is no observer for it (todo: same for PIP)
---
.../org/apache/webbeans/config/BeansDeployer.java | 35 ++-
.../webbeans/config/OpenWebBeansConfiguration.java | 6 +
.../corespi/scanner/AbstractMetaDataDiscovery.java | 14 +-
.../apache/webbeans/event/NotificationManager.java | 309 +++++++++++----------
.../webbeans/portable/AnnotatedElementFactory.java | 2 +-
.../java/org/apache/webbeans/util/ClassUtil.java | 10 +-
6 files changed, 215 insertions(+), 161 deletions(-)
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java b/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
index a7b2337..5eaf2c3 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
@@ -111,6 +111,7 @@ import javax.enterprise.inject.spi.Producer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
@@ -164,6 +165,8 @@ public class BeansDeployer
private final Map<String, Boolean> packageVetoCache = new HashMap<>();
protected boolean skipVetoedOnPackages;
+ protected boolean skipNoClassDefFoundTriggers;
+ protected boolean skipValidations;
/**
* This BdaInfo is used for all manually added annotated types or in case
@@ -188,6 +191,9 @@ public class BeansDeployer
discoverEjb = Boolean.parseBoolean(usage);
skipVetoedOnPackages = Boolean.parseBoolean(this.webBeansContext.getOpenWebBeansConfiguration().getProperty(
"org.apache.webbeans.spi.deployer.skipVetoedOnPackages"));
+ skipValidations = Boolean.parseBoolean(this.webBeansContext.getOpenWebBeansConfiguration().getProperty(
+ "org.apache.webbeans.spi.deployer.skipValidations"));
+ skipNoClassDefFoundTriggers = this.webBeansContext.getOpenWebBeansConfiguration().isSkipNoClassDefFoundErrorTriggers();
defaultBeanArchiveInformation = new DefaultBeanArchiveInformation("default");
defaultBeanArchiveInformation.setBeanDiscoveryMode(BeanDiscoveryMode.ALL);
@@ -313,15 +319,18 @@ public class BeansDeployer
// drop no more needed memory data
webBeansContext.getNotificationManager().afterStart();
- validateAlternatives(beanAttributesPerBda);
+ if (!skipValidations)
+ {
+ validateAlternatives(beanAttributesPerBda);
- validateInjectionPoints();
- validateDisposeParameters();
+ validateInjectionPoints();
+ validateDisposeParameters();
- validateDecoratorDecoratedTypes();
- validateDecoratorGenericTypes();
+ validateDecoratorDecoratedTypes();
+ validateDecoratorGenericTypes();
- validateNames();
+ validateNames();
+ }
if (webBeansContext.getNotificationManager().getObserverMethods().stream()
.anyMatch(ObserverMethod::isAsync))
@@ -1295,10 +1304,11 @@ public class BeansDeployer
if (classIndex != null)
{
AnnotatedElementFactory annotatedElementFactory = webBeansContext.getAnnotatedElementFactory();
-
+ boolean hasPATObserver = webBeansContext.getNotificationManager().hasProcessAnnotatedTypeObservers();
for (Class<?> implClass : classIndex)
{
- if (foundClasses.contains(implClass))
+ if (foundClasses.contains(implClass) || implClass.isAnonymousClass() ||
+ Modifier.isPrivate(implClass.getModifiers() /* likely inner class */))
{
// skip this class
continue;
@@ -1338,11 +1348,14 @@ public class BeansDeployer
// trigger a NoClassDefFoundError here, otherwise it would be thrown in observer methods
Class<?> javaClass = annotatedType.getJavaClass();
- javaClass.getDeclaredMethods();
- javaClass.getDeclaredFields();
+ if (!skipNoClassDefFoundTriggers)
+ {
+ javaClass.getDeclaredMethods();
+ javaClass.getDeclaredFields();
+ }
// Fires ProcessAnnotatedType
- if (!javaClass.isAnnotation())
+ if (hasPATObserver && !javaClass.isAnnotation())
{
GProcessAnnotatedType processAnnotatedEvent = webBeansContext.getWebBeansUtil().fireProcessAnnotatedTypeEvent(annotatedType);
if (!processAnnotatedEvent.isVeto())
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java b/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
index 0d2b480..3810268 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
@@ -550,4 +550,10 @@ public class OpenWebBeansConfiguration
return generatorJavaVersion;
}
+
+ public boolean isSkipNoClassDefFoundErrorTriggers()
+ {
+ return Boolean.parseBoolean(getProperty(
+ "org.apache.webbeans.spi.deployer.skipNoClassDefFoundTriggers"));
+ }
}
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
index 210556e..d09e2b3 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
@@ -412,6 +412,9 @@ public abstract class AbstractMetaDataDiscovery implements BdaScannerService
if (beanClassesPerBda == null)
{
beanClassesPerBda = new HashMap<>();
+ ClassLoader loader = WebBeansUtil.getCurrentClassLoader();
+ boolean dontSkipNCDFT = !(webBeansContext != null &&
+ webBeansContext.getOpenWebBeansConfiguration().isSkipNoClassDefFoundErrorTriggers());
for (CdiArchive.FoundClasses foundClasses : archive.classesByUrl().values())
{
@@ -431,12 +434,15 @@ public abstract class AbstractMetaDataDiscovery implements BdaScannerService
}
}
- Class<?> clazz = ClassUtil.getClassFromName(className);
+ Class<?> clazz = ClassUtil.getClassFromName(className, loader, dontSkipNCDFT);
if (clazz != null)
{
- // try to provoke a NoClassDefFoundError exception which is thrown
- // if some dependencies of the class are missing
- clazz.getDeclaredFields();
+ if (dontSkipNCDFT)
+ {
+ // try to provoke a NoClassDefFoundError exception which is thrown
+ // if some dependencies of the class are missing
+ clazz.getDeclaredFields();
+ }
// we can add this class cause it has been loaded completely
classSet.add(clazz);
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java b/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
index dede48e..3ad6ce0 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
@@ -82,6 +82,7 @@ import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.exception.WebBeansDeploymentException;
import org.apache.webbeans.exception.WebBeansException;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
+import org.apache.webbeans.portable.events.ProcessAnnotatedTypeImpl;
import org.apache.webbeans.portable.events.generics.GProcessObserverMethod;
import org.apache.webbeans.portable.events.generics.GenericBeanEvent;
import org.apache.webbeans.portable.events.generics.GenericProducerObserverEvent;
@@ -95,6 +96,7 @@ import org.apache.webbeans.util.GenericsUtil;
import org.apache.webbeans.util.WebBeansUtil;
import static java.util.Collections.emptyList;
+import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.stream.Collectors.toMap;
public final class NotificationManager
@@ -229,196 +231,211 @@ public final class NotificationManager
set.add(observer);
}
+ public boolean hasProcessAnnotatedTypeObservers()
+ {
+ cacheIfNeeded(new ProcessAnnotatedTypeImpl<>(null, null));
+ return !processAnnotatedTypeObservers.isEmpty();
+ }
public <T> Collection<ObserverMethod<? super T>> resolveObservers(T event, EventMetadataImpl metadata, boolean isLifecycleEvent)
{
if (isLifecycleEvent) // goal here is to skip any resolution if not needed
{
- if (event instanceof ProcessAnnotatedType)
+ Collection<ObserverMethod<?>> observerMethods = cacheIfNeeded(event);
+ if (observerMethods != null) // emptyList()
{
- if (processAnnotatedTypeObservers == null)
- {
- processAnnotatedTypeObservers = findObservers(ProcessAnnotatedType.class);
- }
- if (processAnnotatedTypeObservers.isEmpty())
- {
- return emptyList();
- }
+ return emptyList();
}
- else if (event instanceof ProcessManagedBean)
+ }
+ Type eventType = metadata.validatedType();
+ Collection<ObserverMethod<? super T>> observersMethods = filterByQualifiers(
+ filterByType(event, eventType, isLifecycleEvent), metadata.getQualifiers());
+
+ if (isLifecycleEvent && event instanceof ProcessAnnotatedType)
+ {
+ observersMethods = filterByWithAnnotations(observersMethods, ((ProcessAnnotatedType) event).getAnnotatedType());
+ }
+ else if (!isLifecycleEvent && observersMethods.isEmpty())
+ {
+ //this check for the TCK is only needed if no observer was found
+ EventUtil.checkEventBindings(webBeansContext, metadata.getQualifiers());
+ EventUtil.checkQualifierImplementations(metadata.getQualifiers());
+ }
+
+ return observersMethods;
+ }
+
+ private <T> Collection<ObserverMethod<?>> cacheIfNeeded(final T event)
+ {
+ if (event instanceof ProcessAnnotatedType)
+ {
+ if (processAnnotatedTypeObservers == null)
{
- if (processManagedBeanObservers == null)
- {
- processManagedBeanObservers = findObservers(ProcessManagedBean.class);
- if (processBeanObservers == null)
- {
- processBeanObservers = findObservers(ProcessBean.class);
- }
- processBeanObservers.forEach((k, v) -> processManagedBeanObservers
- .computeIfAbsent(k, it -> new HashSet<>())
- .addAll(v));
- }
- if (processManagedBeanObservers.isEmpty())
- {
- return emptyList();
- }
+ processAnnotatedTypeObservers = findObservers(ProcessAnnotatedType.class);
}
- else if (event instanceof ProcessProducerField)
+ if (processAnnotatedTypeObservers.isEmpty())
{
- if (processProducerFieldObservers == null)
- {
- processProducerFieldObservers = findObservers(ProcessProducerField.class);
- if (processBeanObservers == null)
- {
- processBeanObservers = findObservers(ProcessBean.class);
- }
- processBeanObservers.forEach((k, v) -> processProducerFieldObservers
- .computeIfAbsent(k, it -> new HashSet<>())
- .addAll(v));
- }
- if (processProducerFieldObservers.isEmpty())
- {
- return emptyList();
- }
+ return emptyList();
}
- else if (event instanceof ProcessProducerMethod)
+ }
+ else if (event instanceof ProcessManagedBean)
+ {
+ if (processManagedBeanObservers == null)
{
- if (processProducerMethodObservers == null)
- {
- processProducerMethodObservers = findObservers(ProcessProducerMethod.class);
- if (processBeanObservers == null)
- {
- processBeanObservers = findObservers(ProcessBean.class);
- }
- processBeanObservers.forEach((k, v) -> processProducerMethodObservers
- .computeIfAbsent(k, it -> new HashSet<>())
- .addAll(v));
- }
- if (processProducerMethodObservers.isEmpty())
+ processManagedBeanObservers = findObservers(ProcessManagedBean.class);
+ if (processBeanObservers == null)
{
- return emptyList();
+ processBeanObservers = findObservers(ProcessBean.class);
}
+ processBeanObservers.forEach((k, v) -> processManagedBeanObservers
+ .computeIfAbsent(k, it -> new HashSet<>())
+ .addAll(v));
}
- else if (event instanceof ProcessSyntheticBean)
+ if (processManagedBeanObservers.isEmpty())
{
- if (processSyntheticBeanObservers == null)
- {
- processSyntheticBeanObservers = findObservers(ProcessSyntheticBean.class);
- if (processBeanObservers == null)
- {
- processBeanObservers = findObservers(ProcessBean.class);
- }
- processBeanObservers.forEach((k, v) -> processSyntheticBeanObservers
- .computeIfAbsent(k, it -> new HashSet<>())
- .addAll(v));
- }
- if (processSyntheticBeanObservers.isEmpty())
- {
- return emptyList();
- }
+ return emptyList();
}
- else if (event instanceof ProcessSyntheticObserverMethod)
+ }
+ else if (event instanceof ProcessProducerField)
+ {
+ if (processProducerFieldObservers == null)
{
- if (processSyntheticObserverMethodObservers == null)
- {
- processSyntheticObserverMethodObservers = findObservers(ProcessSyntheticObserverMethod.class);
- if (processObserverMethodObservers == null)
- {
- processObserverMethodObservers = findObservers(ProcessObserverMethod.class);
- }
- processObserverMethodObservers.forEach((k, v) -> processSyntheticObserverMethodObservers
- .computeIfAbsent(k, it -> new HashSet<>())
- .addAll(v));
- }
- if (processSyntheticObserverMethodObservers.isEmpty())
+ processProducerFieldObservers = findObservers(ProcessProducerField.class);
+ if (processBeanObservers == null)
{
- return emptyList();
+ processBeanObservers = findObservers(ProcessBean.class);
}
+ processBeanObservers.forEach((k, v) -> processProducerFieldObservers
+ .computeIfAbsent(k, it -> new HashSet<>())
+ .addAll(v));
}
- else if (event instanceof ProcessBean)
+ if (processProducerFieldObservers.isEmpty())
{
+ return emptyList();
+ }
+ }
+ else if (event instanceof ProcessProducerMethod)
+ {
+ if (processProducerMethodObservers == null)
+ {
+ processProducerMethodObservers = findObservers(ProcessProducerMethod.class);
if (processBeanObservers == null)
{
processBeanObservers = findObservers(ProcessBean.class);
}
- if (processBeanObservers.isEmpty())
- {
- return emptyList();
- }
+ processBeanObservers.forEach((k, v) -> processProducerMethodObservers
+ .computeIfAbsent(k, it -> new HashSet<>())
+ .addAll(v));
}
- else if (event instanceof ProcessBeanAttributes)
+ if (processProducerMethodObservers.isEmpty())
{
- if (processBeanAttributesObservers == null)
- {
- processBeanAttributesObservers = findObservers(ProcessBeanAttributes.class);
- }
- if (processBeanAttributesObservers.isEmpty())
- {
- return emptyList();
- }
+ return emptyList();
}
- else if (event instanceof ProcessInjectionTarget)
+ }
+ else if (event instanceof ProcessSyntheticBean)
+ {
+ if (processSyntheticBeanObservers == null)
{
- if (processInjectionTargetObservers == null)
- {
- processInjectionTargetObservers = findObservers(ProcessInjectionTarget.class);
- }
- if (processInjectionTargetObservers.isEmpty())
+ processSyntheticBeanObservers = findObservers(ProcessSyntheticBean.class);
+ if (processBeanObservers == null)
{
- return emptyList();
+ processBeanObservers = findObservers(ProcessBean.class);
}
+ processBeanObservers.forEach((k, v) -> processSyntheticBeanObservers
+ .computeIfAbsent(k, it -> new HashSet<>())
+ .addAll(v));
}
- else if (event instanceof ProcessInjectionPoint)
+ if (processSyntheticBeanObservers.isEmpty())
{
- if (processInjectionPointObservers == null)
- {
- processInjectionPointObservers = findObservers(ProcessInjectionPoint.class);
- }
- if (processInjectionPointObservers.isEmpty())
- {
- return emptyList();
- }
+ return emptyList();
}
- else if (event instanceof ProcessObserverMethod)
+ }
+ else if (event instanceof ProcessSyntheticObserverMethod)
+ {
+ if (processSyntheticObserverMethodObservers == null)
{
+ processSyntheticObserverMethodObservers = findObservers(ProcessSyntheticObserverMethod.class);
if (processObserverMethodObservers == null)
{
processObserverMethodObservers = findObservers(ProcessObserverMethod.class);
}
- if (processObserverMethodObservers.isEmpty())
- {
- return emptyList();
- }
+ processObserverMethodObservers.forEach((k, v) -> processSyntheticObserverMethodObservers
+ .computeIfAbsent(k, it -> new HashSet<>())
+ .addAll(v));
}
- else if (event instanceof ProcessProducer)
+ if (processSyntheticObserverMethodObservers.isEmpty())
{
- if (processProducerObservers == null)
- {
- processProducerObservers = findObservers(ProcessProducer.class);
- }
- if (processProducerObservers.isEmpty())
- {
- return emptyList();
- }
+ return emptyList();
}
- // note: don't forget to update filterByExtensionEventType method too
}
- Type eventType = metadata.validatedType();
- Collection<ObserverMethod<? super T>> observersMethods = filterByQualifiers(
- filterByType(event, eventType, isLifecycleEvent), metadata.getQualifiers());
-
- if (isLifecycleEvent && event instanceof ProcessAnnotatedType)
+ else if (event instanceof ProcessBean)
{
- observersMethods = filterByWithAnnotations(observersMethods, ((ProcessAnnotatedType) event).getAnnotatedType());
+ if (processBeanObservers == null)
+ {
+ processBeanObservers = findObservers(ProcessBean.class);
+ }
+ if (processBeanObservers.isEmpty())
+ {
+ return emptyList();
+ }
}
- else if (!isLifecycleEvent && observersMethods.isEmpty())
+ else if (event instanceof ProcessBeanAttributes)
{
- //this check for the TCK is only needed if no observer was found
- EventUtil.checkEventBindings(webBeansContext, metadata.getQualifiers());
- EventUtil.checkQualifierImplementations(metadata.getQualifiers());
+ if (processBeanAttributesObservers == null)
+ {
+ processBeanAttributesObservers = findObservers(ProcessBeanAttributes.class);
+ }
+ if (processBeanAttributesObservers.isEmpty())
+ {
+ return emptyList();
+ }
}
-
- return observersMethods;
+ else if (event instanceof ProcessInjectionTarget)
+ {
+ if (processInjectionTargetObservers == null)
+ {
+ processInjectionTargetObservers = findObservers(ProcessInjectionTarget.class);
+ }
+ if (processInjectionTargetObservers.isEmpty())
+ {
+ return emptyList();
+ }
+ }
+ else if (event instanceof ProcessInjectionPoint)
+ {
+ if (processInjectionPointObservers == null)
+ {
+ processInjectionPointObservers = findObservers(ProcessInjectionPoint.class);
+ }
+ if (processInjectionPointObservers.isEmpty())
+ {
+ return emptyList();
+ }
+ }
+ else if (event instanceof ProcessObserverMethod)
+ {
+ if (processObserverMethodObservers == null)
+ {
+ processObserverMethodObservers = findObservers(ProcessObserverMethod.class);
+ }
+ if (processObserverMethodObservers.isEmpty())
+ {
+ return emptyList();
+ }
+ }
+ else if (event instanceof ProcessProducer)
+ {
+ if (processProducerObservers == null)
+ {
+ processProducerObservers = findObservers(ProcessProducer.class);
+ }
+ if (processProducerObservers.isEmpty())
+ {
+ return emptyList();
+ }
+ }
+ // note: don't forget to update filterByExtensionEventType method too
+ return null;
}
private <T> Collection<ObserverMethod<? super T>> filterByWithAnnotations(Collection<ObserverMethod<? super T>> observersMethods, AnnotatedType annotatedType)
@@ -921,6 +938,14 @@ public final class NotificationManager
List<ObserverMethod<? super Object>> observerMethods)
{
prepareObserverListForFire(isLifecycleEvent, async, observerMethods);
+ if (observerMethods.isEmpty())
+ {
+ if (async)
+ {
+ return completedFuture((T) event);
+ }
+ return null;
+ }
EventContextImpl<Object> context = new EventContextImpl<>(event, metadata);
if (async)
{
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java b/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java
index afa78bc..460c932 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java
@@ -394,6 +394,6 @@ public final class AnnotatedElementFactory
annotatedTypes = oldAnnotatedTypes;
}
}
- return (ConcurrentMap<String, AnnotatedType<T>>)(ConcurrentMap<?, ?>)annotatedTypes;
+ return ConcurrentMap.class.cast(annotatedTypes);
}
}
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java b/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
index 2ecce48..67b4540 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/util/ClassUtil.java
@@ -89,12 +89,16 @@ public final class ClassUtil
public static Class<?> getClassFromName(String name)
{
+ return getClassFromName(name, WebBeansUtil.getCurrentClassLoader(), true);
+ }
+
+ public static Class<?> getClassFromName(String name, ClassLoader providedLoader, boolean init)
+ {
Class<?> clazz;
- ClassLoader loader;
+ ClassLoader loader = providedLoader;
try
{
- loader = WebBeansUtil.getCurrentClassLoader();
- clazz = Class.forName(name, true , loader);
+ clazz = Class.forName(name, init , loader);
return clazz;
}