Search in sources :

Example 1 with ObserverMethod

use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.

the class BeanManagerImpl method removeUnusedBeans.

private void removeUnusedBeans() {
    String excludeTypeProperty = getServices().get(WeldConfiguration.class).getStringProperty(ConfigurationKey.UNUSED_BEANS_EXCLUDE_TYPE);
    if (UnusedBeans.isEnabled(excludeTypeProperty)) {
        String excludeAnnotationProperty = getServices().get(WeldConfiguration.class).getStringProperty(ConfigurationKey.UNUSED_BEANS_EXCLUDE_ANNOTATION);
        // Init exclude patterns
        Pattern excludeAnnotation = excludeAnnotationProperty.isEmpty() ? null : Pattern.compile(excludeAnnotationProperty);
        Pattern excludeType = UnusedBeans.excludeNone(excludeTypeProperty) ? null : Pattern.compile(excludeTypeProperty);
        Validator validator = getServices().get(Validator.class);
        // Build bean to declared producers and declared observers maps
        SetMultimap<Bean<?>, AbstractProducerBean<?, ?, ?>> beanToDeclaredProducers = SetMultimap.newSetMultimap();
        SetMultimap<Bean<?>, ObserverMethod<?>> beanToDeclaredObservers = SetMultimap.newSetMultimap();
        for (Bean<?> bean : enabledBeans) {
            if (bean instanceof AbstractProducerBean) {
                AbstractProducerBean<?, ?, ?> producer = (AbstractProducerBean<?, ?, ?>) bean;
                beanToDeclaredProducers.put(producer.getDeclaringBean(), producer);
            }
        }
        for (ObserverMethod<?> observerMethod : observers) {
            if (observerMethod instanceof ObserverMethodImpl) {
                ObserverMethodImpl<?, ?> observerMethodImpl = (ObserverMethodImpl<?, ?>) observerMethod;
                beanToDeclaredObservers.put(observerMethodImpl.getDeclaringBean(), observerMethod);
            }
        }
        Set<Bean<?>> removable = new HashSet<>();
        Set<Bean<?>> unusedProducers = new HashSet<>();
        WeldUnusedMetadataExtension metadataExtension = getUnusedMetadataExtension();
        for (Bean<?> bean : enabledBeans) {
            bean = Beans.unwrap(bean);
            // Built-in bean, extension, interceptor, decorator, session bean
            if (bean instanceof AbstractBuiltInBean || bean instanceof ExtensionBean || bean instanceof Interceptor || bean instanceof Decorator || bean instanceof SessionBean) {
                continue;
            }
            // Has a name
            if (bean.getName() != null) {
                continue;
            }
            // The type is excluded
            if (excludeType != null && excludeType.matcher(bean.getBeanClass().getName()).matches()) {
                continue;
            }
            // Declares an observer
            if (beanToDeclaredObservers.containsKey(bean)) {
                continue;
            }
            // Declares a used producer - see also second pass
            if (beanToDeclaredProducers.containsKey(bean)) {
                continue;
            }
            // Is resolved for an injection point
            if (validator.isResolved(bean) || (metadataExtension != null && (metadataExtension.isInjectedByEEComponent(bean, this) || metadataExtension.isInstanceResolvedBean(bean, this)))) {
                continue;
            }
            // The type is annotated with an exclude annotation
            if (excludeAnnotation != null && hasExcludeAnnotation(bean, excludeAnnotation)) {
                continue;
            }
            // This bean is very likely an unused producer
            if (bean instanceof AbstractProducerBean) {
                unusedProducers.add(bean);
            }
            BootstrapLogger.LOG.dropUnusedBeanMetadata(bean);
            removable.add(bean);
        }
        // Second pass to find beans which themselves are unused and declare only unused producers
        if (!unusedProducers.isEmpty()) {
            for (Bean<?> bean : beanToDeclaredProducers.keySet()) {
                bean = Beans.unwrap(bean);
                if (!unusedProducers.containsAll(beanToDeclaredProducers.get(bean))) {
                    continue;
                }
                BootstrapLogger.LOG.dropUnusedBeanMetadata(bean);
                removable.add(bean);
            }
        }
        if (!removable.isEmpty()) {
            // First remove unused beans from BeanManager
            enabledBeans.removeAll(removable);
            sharedBeans.removeAll(removable);
            // Then perform additional cleanup
            beanResolver.clear();
            // Removed beans are skipped in WeldStartup.endInitialization()
            cleanupBeansAfterBoot(removable);
            ((ContextualStoreImpl) getServices().get(ContextualStore.class)).removeAll(removable);
            getServices().get(ClassTransformer.class).removeAll(removable);
        }
    }
}
Also used : ClassTransformer(org.jboss.weld.resources.ClassTransformer) SessionBean(org.jboss.weld.bean.SessionBean) SessionBean(org.jboss.weld.bean.SessionBean) ExtensionBean(org.jboss.weld.bean.builtin.ExtensionBean) AbstractClassBean(org.jboss.weld.bean.AbstractClassBean) AbstractBuiltInBean(org.jboss.weld.bean.builtin.AbstractBuiltInBean) WeldBean(org.jboss.weld.bean.WeldBean) RIBean(org.jboss.weld.bean.RIBean) AbstractProducerBean(org.jboss.weld.bean.AbstractProducerBean) Bean(jakarta.enterprise.inject.spi.Bean) WeldUnusedMetadataExtension(org.jboss.weld.bootstrap.WeldUnusedMetadataExtension) ObserverMethodImpl(org.jboss.weld.event.ObserverMethodImpl) Interceptor(jakarta.enterprise.inject.spi.Interceptor) ContainerLifecycleEventObserverMethod(org.jboss.weld.event.ContainerLifecycleEventObserverMethod) ObserverMethod(jakarta.enterprise.inject.spi.ObserverMethod) HashSet(java.util.HashSet) ContextualStoreImpl(org.jboss.weld.serialization.ContextualStoreImpl) Pattern(java.util.regex.Pattern) AbstractBuiltInBean(org.jboss.weld.bean.builtin.AbstractBuiltInBean) AbstractProducerBean(org.jboss.weld.bean.AbstractProducerBean) ExtensionBean(org.jboss.weld.bean.builtin.ExtensionBean) Decorator(jakarta.enterprise.inject.spi.Decorator) ContextualStore(org.jboss.weld.serialization.spi.ContextualStore) WeldConfiguration(org.jboss.weld.config.WeldConfiguration) AnnotatedTypeValidator(org.jboss.weld.annotated.AnnotatedTypeValidator) Validator(org.jboss.weld.bootstrap.Validator)

Example 2 with ObserverMethod

use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.

the class ProbeObserver method notify.

@Override
public void notify(Object event) {
    EventMetadata metadata = currentEventMetadata.peek();
    if (excludePattern != null && excludePattern.matcher(Formats.formatType(metadata.getType(), false)).matches()) {
        ProbeLogger.LOG.eventExcluded(metadata.getType());
        return;
    }
    boolean containerEvent = isContainerEvent(metadata.getQualifiers());
    List<ObserverMethod<?>> observers = resolveObservers(metadata, containerEvent);
    EventInfo info = new EventInfo(metadata.getType(), metadata.getQualifiers(), event, metadata.getInjectionPoint(), observers, containerEvent, System.currentTimeMillis());
    probe.addEvent(info);
}
Also used : CurrentEventMetadata(org.jboss.weld.event.CurrentEventMetadata) EventMetadata(jakarta.enterprise.inject.spi.EventMetadata) ObserverMethod(jakarta.enterprise.inject.spi.ObserverMethod)

Example 3 with ObserverMethod

use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.

the class ObserverNotifier method notifyAsyncObservers.

protected <T, U extends T> CompletionStage<U> notifyAsyncObservers(List<ObserverMethod<? super T>> observers, U event, EventMetadata metadata, Executor executor, NotificationOptions options) {
    if (executor == null) {
        executor = asyncEventExecutor;
    }
    if (observers.isEmpty()) {
        return AsyncEventDeliveryStage.completed(event, executor);
    }
    // We should always initialize and validate all notification options first
    final NotificationMode mode = initModeOption(options.get(WeldNotificationOptions.MODE));
    final Long timeout = initTimeoutOption(options.get(WeldNotificationOptions.TIMEOUT));
    final Consumer<Runnable> securityContextActionConsumer = securityServices.getSecurityContextAssociator();
    // grab current TCCL
    ClassLoader tccl = SecurityActions.getContextClassLoader();
    final ObserverExceptionHandler exceptionHandler;
    CompletableFuture<U> completableFuture;
    if (observers.size() > 1 && NotificationMode.PARALLEL.equals(mode)) {
        // Attempt to notify async observers in parallel
        exceptionHandler = new CollectingExceptionHandler(new CopyOnWriteArrayList<>());
        List<CompletableFuture<T>> completableFutures = new ArrayList<>(observers.size());
        for (ObserverMethod<? super T> observer : observers) {
            completableFutures.add(CompletableFuture.supplyAsync(createSupplier(tccl, securityContextActionConsumer, event, metadata, exceptionHandler, false, () -> {
                notifyAsyncObserver(observer, event, metadata, exceptionHandler);
            }), executor));
        }
        completableFuture = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[] {})).thenApply((ignoredVoid) -> {
            handleExceptions(exceptionHandler);
            return event;
        });
    } else {
        // Async observers are notified serially in a single worker thread
        exceptionHandler = new CollectingExceptionHandler();
        completableFuture = CompletableFuture.supplyAsync(createSupplier(tccl, securityContextActionConsumer, event, metadata, exceptionHandler, true, () -> {
            for (ObserverMethod<? super T> observer : observers) {
                notifyAsyncObserver(observer, event, metadata, exceptionHandler);
            }
        }), executor);
    }
    // If NotificationOptionKeys.TIMEOUT is set, we will trigger the counter and use CompletableFuture.anyOf()
    if (timeout != null) {
        completableFuture = CompletableFuture.anyOf(completableFuture, startTimer(timeout)).thenApply((ignoredObject) -> event);
    }
    return new AsyncEventDeliveryStage<>(completableFuture, executor);
}
Also used : ServiceRegistry(org.jboss.weld.bootstrap.api.ServiceRegistry) WeldNotificationOptions(org.jboss.weld.events.WeldNotificationOptions) EventLogger(org.jboss.weld.logging.EventLogger) Reflections(org.jboss.weld.util.reflection.Reflections) SharedObjectCache(org.jboss.weld.resources.SharedObjectCache) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) Types(org.jboss.weld.util.Types) Reflections.cast(org.jboss.weld.util.reflection.Reflections.cast) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) ComputingCache(org.jboss.weld.util.cache.ComputingCache) QualifierInstance(org.jboss.weld.resolution.QualifierInstance) LazyValueHolder(org.jboss.weld.util.LazyValueHolder) SecurityServices(org.jboss.weld.security.spi.SecurityServices) ExecutorServices(org.jboss.weld.manager.api.ExecutorServices) Observers(org.jboss.weld.util.Observers) UtilLogger(org.jboss.weld.logging.UtilLogger) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ObserverException(jakarta.enterprise.event.ObserverException) RequestContext(org.jboss.weld.context.RequestContext) LinkedList(java.util.LinkedList) ResolvableBuilder(org.jboss.weld.resolution.ResolvableBuilder) EventMetadata(jakarta.enterprise.inject.spi.EventMetadata) ThreadLocalStackReference(org.jboss.weld.injection.ThreadLocalStack.ThreadLocalStackReference) NotificationMode(org.jboss.weld.events.WeldNotificationOptions.NotificationMode) Executor(java.util.concurrent.Executor) UnboundLiteral(org.jboss.weld.context.unbound.UnboundLiteral) Set(java.util.Set) ObserverMethod(jakarta.enterprise.inject.spi.ObserverMethod) CompletionException(java.util.concurrent.CompletionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Resolvable(org.jboss.weld.resolution.Resolvable) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) NotificationOptions(jakarta.enterprise.event.NotificationOptions) ComputingCacheBuilder(org.jboss.weld.util.cache.ComputingCacheBuilder) Type(java.lang.reflect.Type) ForkJoinPool(java.util.concurrent.ForkJoinPool) Annotation(java.lang.annotation.Annotation) Collections(java.util.Collections) TypeSafeObserverResolver(org.jboss.weld.resolution.TypeSafeObserverResolver) Container(org.jboss.weld.Container) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) NotificationMode(org.jboss.weld.events.WeldNotificationOptions.NotificationMode) ArrayList(java.util.ArrayList) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) CompletableFuture(java.util.concurrent.CompletableFuture) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 4 with ObserverMethod

use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.

the class Probe method findUnusedBeans.

private void findUnusedBeans() {
    Collection<Bean<?>> beans = idToBean.values();
    Collection<ObserverMethod<?>> observers = idToObserver.values();
    for (Bean<?> bean : beans) {
        BeanKind kind = BeanKind.from(bean);
        if (BeanKind.BUILT_IN.equals(kind) || BeanKind.EXTENSION.equals(kind) || BeanKind.DECORATOR.equals(kind) || BeanKind.INTERCEPTOR.equals(kind)) {
            continue;
        }
        if (bean.getName() != null) {
            // Is annotated with @Named
            continue;
        }
        if (!(BeanKind.PRODUCER_FIELD.equals(kind) || BeanKind.PRODUCER_METHOD.equals(kind)) && !getDeclaredProducers(bean).isEmpty()) {
            // Has declared producers
            continue;
        }
        if (Components.hasDependents(bean, beans, this)) {
            // Has direct or potential (Instance<>) dependents
            continue;
        }
        if (hasDeclaredObserversOrIsInjectedIntoObserver(bean, observers)) {
            continue;
        }
        if (isInjectedIntoDisposer(bean, beans)) {
            continue;
        }
        unusedBeans.add(bean);
    }
}
Also used : BeanKind(org.jboss.weld.probe.Components.BeanKind) AbstractProducerBean(org.jboss.weld.bean.AbstractProducerBean) ExtensionBean(org.jboss.weld.bean.builtin.ExtensionBean) Bean(jakarta.enterprise.inject.spi.Bean) AbstractBuiltInBean(org.jboss.weld.bean.builtin.AbstractBuiltInBean) ObserverMethod(jakarta.enterprise.inject.spi.ObserverMethod)

Example 5 with ObserverMethod

use of jakarta.enterprise.inject.spi.ObserverMethod in project core by weld.

the class ProbeObserver method resolveObservers.

private List<ObserverMethod<?>> resolveObservers(EventMetadata metadata, boolean containerEvent) {
    List<ObserverMethod<?>> observers = new ArrayList<ObserverMethod<?>>();
    final ObserverNotifier notifier = (containerEvent) ? manager.getAccessibleLenientObserverNotifier() : manager.getGlobalLenientObserverNotifier();
    ResolvedObservers<?> resolvedObservers = notifier.resolveObserverMethods(metadata.getType(), metadata.getQualifiers());
    for (ObserverMethod<?> observer : resolvedObservers.getAllObservers()) {
        // do not show ProbeObserver
        if (getBeanClass() != observer.getBeanClass()) {
            observers.add(observer);
        }
    }
    return ImmutableList.copyOf(observers);
}
Also used : ArrayList(java.util.ArrayList) ObserverNotifier(org.jboss.weld.event.ObserverNotifier) ObserverMethod(jakarta.enterprise.inject.spi.ObserverMethod)

Aggregations

ObserverMethod (jakarta.enterprise.inject.spi.ObserverMethod)5 Bean (jakarta.enterprise.inject.spi.Bean)2 EventMetadata (jakarta.enterprise.inject.spi.EventMetadata)2 ArrayList (java.util.ArrayList)2 AbstractProducerBean (org.jboss.weld.bean.AbstractProducerBean)2 AbstractBuiltInBean (org.jboss.weld.bean.builtin.AbstractBuiltInBean)2 ExtensionBean (org.jboss.weld.bean.builtin.ExtensionBean)2 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 NotificationOptions (jakarta.enterprise.event.NotificationOptions)1 ObserverException (jakarta.enterprise.event.ObserverException)1 Decorator (jakarta.enterprise.inject.spi.Decorator)1 Interceptor (jakarta.enterprise.inject.spi.Interceptor)1 Annotation (java.lang.annotation.Annotation)1 Type (java.lang.reflect.Type)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Set (java.util.Set)1 CompletableFuture (java.util.concurrent.CompletableFuture)1