All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.webbeans.config.BeansDeployer Maven / Gradle / Ivy

There is a newer version: 10.0.0-M3
Show newest version
/*
 * 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.webbeans.config;

import org.apache.webbeans.annotation.AnnotationManager;
import org.apache.webbeans.annotation.AnyLiteral;
import org.apache.webbeans.component.AbstractProducerBean;
import org.apache.webbeans.component.BeanAttributesImpl;
import org.apache.webbeans.component.BuiltInOwbBean;
import org.apache.webbeans.component.CdiInterceptorBean;
import org.apache.webbeans.component.DecoratorBean;
import org.apache.webbeans.component.EnterpriseBeanMarker;
import org.apache.webbeans.component.InjectionTargetBean;
import org.apache.webbeans.component.ManagedBean;
import org.apache.webbeans.component.OwbBean;
import org.apache.webbeans.component.ProducerFieldBean;
import org.apache.webbeans.component.ProducerMethodBean;
import org.apache.webbeans.component.creation.BeanAttributesBuilder;
import org.apache.webbeans.component.creation.CdiInterceptorBeanBuilder;
import org.apache.webbeans.component.creation.DecoratorBeanBuilder;
import org.apache.webbeans.component.creation.ManagedBeanBuilder;
import org.apache.webbeans.component.creation.ObserverMethodsBuilder;
import org.apache.webbeans.component.creation.ProducerFieldBeansBuilder;
import org.apache.webbeans.component.creation.ProducerMethodBeansBuilder;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.container.InjectableBeanManager;
import org.apache.webbeans.container.InjectionResolver;
import org.apache.webbeans.corespi.se.DefaultJndiService;
import org.apache.webbeans.decorator.DecoratorsManager;
import org.apache.webbeans.deployment.StereoTypeManager;
import org.apache.webbeans.deployment.StereoTypeModel;
import org.apache.webbeans.event.ObserverMethodImpl;
import org.apache.webbeans.event.OwbObserverMethod;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.exception.WebBeansDeploymentException;
import org.apache.webbeans.exception.WebBeansException;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.Vetoed;
import javax.enterprise.inject.spi.BeanAttributes;
import javax.enterprise.inject.spi.DefinitionException;

import org.apache.webbeans.inject.AlternativesManager;
import org.apache.webbeans.intercept.InterceptorsManager;
import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.portable.AbstractProducer;
import org.apache.webbeans.portable.AnnotatedElementFactory;
import org.apache.webbeans.portable.BaseProducerProducer;
import org.apache.webbeans.portable.events.ProcessBeanImpl;
import org.apache.webbeans.portable.events.ProcessSyntheticAnnotatedTypeImpl;
import org.apache.webbeans.portable.events.discovery.AfterBeanDiscoveryImpl;
import org.apache.webbeans.portable.events.discovery.AfterDeploymentValidationImpl;
import org.apache.webbeans.portable.events.discovery.AfterTypeDiscoveryImpl;
import org.apache.webbeans.portable.events.discovery.BeforeBeanDiscoveryImpl;
import org.apache.webbeans.portable.events.generics.GProcessAnnotatedType;
import org.apache.webbeans.portable.events.generics.GProcessManagedBean;
import org.apache.webbeans.spi.BdaScannerService;
import org.apache.webbeans.spi.BeanArchiveService;
import org.apache.webbeans.spi.JNDIService;
import org.apache.webbeans.spi.ScannerService;
import org.apache.webbeans.spi.plugins.OpenWebBeansJavaEEPlugin;
import org.apache.webbeans.util.AnnotationUtil;
import org.apache.webbeans.util.ClassUtil;
import org.apache.webbeans.util.ExceptionUtil;
import org.apache.webbeans.util.GenericsUtil;
import org.apache.webbeans.util.InjectionExceptionUtil;
import org.apache.webbeans.util.SpecializationUtil;
import org.apache.webbeans.util.WebBeansConstants;
import org.apache.webbeans.util.WebBeansUtil;
import org.apache.webbeans.xml.DefaultBeanArchiveInformation;

import javax.enterprise.inject.AmbiguousResolutionException;
import javax.enterprise.inject.Model;
import javax.enterprise.inject.UnproxyableResolutionException;
import javax.enterprise.inject.UnsatisfiedResolutionException;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.Interceptor;
import javax.enterprise.inject.spi.ObserverMethod;
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.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

import static java.util.Arrays.asList;
import static org.apache.webbeans.spi.BeanArchiveService.BeanDiscoveryMode;
import static org.apache.webbeans.spi.BeanArchiveService.BeanArchiveInformation;

/**
 * Deploys the all beans that are defined in the {@link org.apache.webbeans.spi.ScannerService} at
 * the scanner phase.
 */
@SuppressWarnings("unchecked")
//This class written as single threaded.
public class BeansDeployer
{
    //Logger instance
    private static final Logger logger = WebBeansLoggerFacade.getLogger(BeansDeployer.class);
    public static final String JAVAX_ENTERPRISE_PACKAGE = "javax.enterprise.";

    private static final Method GET_PACKAGE;
    static
    {
        Method getPackage;
        try
        {
            getPackage = ClassLoader.class.getDeclaredMethod("getDefinedPackage", String.class);
            getPackage.setAccessible(true);
        }
        catch (final NoSuchMethodException e)
        {
            try
            {
                getPackage = ClassLoader.class.getDeclaredMethod("getPackage", String.class);
                getPackage.setAccessible(true);
            }
            catch (final NoSuchMethodException ex)
            {
                throw new IllegalStateException(ex);
            }
        }
        GET_PACKAGE = getPackage;
    }


    /**Deployment is started or not*/
    protected boolean deployed = false;

    /**XML Configurator*/
    protected BeanArchiveService beanArchiveService;
    
    /**Discover ejb or not*/
    protected boolean discoverEjb = false;
    private final WebBeansContext webBeansContext;

    private final ScannerService scannerService;
    private final DecoratorsManager decoratorsManager;
    private final InterceptorsManager interceptorsManager;

    private final Map packageVetoCache = new HashMap();

    /**
     * This BdaInfo is used for all manually added annotated types or in case
     * a non-Bda-aware ScannerService got configured.
     */
    private final DefaultBeanArchiveInformation defaultBeanArchiveInformation;

    /**
     * Creates a new deployer with given xml configurator.
     * 
     * @param webBeansContext
     */
    public BeansDeployer(WebBeansContext webBeansContext)
    {
        this.webBeansContext = webBeansContext;
        beanArchiveService = webBeansContext.getBeanArchiveService();
        scannerService = webBeansContext.getScannerService();
        decoratorsManager = webBeansContext.getDecoratorsManager();
        interceptorsManager = webBeansContext.getInterceptorsManager();

        String usage = this.webBeansContext.getOpenWebBeansConfiguration().getProperty(OpenWebBeansConfiguration.USE_EJB_DISCOVERY);
        discoverEjb = Boolean.parseBoolean(usage);

        defaultBeanArchiveInformation = new DefaultBeanArchiveInformation("default");
        defaultBeanArchiveInformation.setBeanDiscoveryMode(BeanDiscoveryMode.ALL);
    }

    /**
     * Deploys all the defined web beans components in the container startup.
     * 

* It deploys from the web-beans.xml files and from the class files. It uses * the {@link org.apache.webbeans.spi.ScannerService} to get classes. *

* * @throws WebBeansDeploymentException if any deployment exception occurs */ public synchronized void deploy(ScannerService scanner) { try { if (!deployed) { //Load Extensions webBeansContext.getExtensionLoader().loadExtensionServices(); // Bind manager JNDIService service = webBeansContext.getService(JNDIService.class); //Default jndi is just a map if(service instanceof DefaultJndiService) { service.bind(WebBeansConstants.WEB_BEANS_MANAGER_JNDI_NAME, new InjectableBeanManager(webBeansContext.getBeanManagerImpl())); } //Assume, actual JNDI implementation else { service.bind(WebBeansConstants.WEB_BEANS_MANAGER_JNDI_NAME, webBeansContext.getBeanManagerImpl().getReference()); } // Register Manager built-in component webBeansContext.getBeanManagerImpl().addInternalBean(webBeansContext.getWebBeansUtil().getManagerBean()); webBeansContext.getBeanManagerImpl().getInjectionResolver().setStartup(true); //Fire Event fireBeforeBeanDiscoveryEvent(); //Configure Default Beans configureDefaultBeans(); Map>> annotatedTypesPerBda = annotatedTypesFromClassPath(scanner); List> globalBdaAnnotatedTypes = annotatedTypesPerBda.get(defaultBeanArchiveInformation); // Deploy additional Annotated Types which got added via BeforeBeanDiscovery#addAnnotatedType addAdditionalAnnotatedTypes(webBeansContext.getBeanManagerImpl().getAdditionalAnnotatedTypes(), globalBdaAnnotatedTypes); for (List> at : annotatedTypesPerBda.values()) { registerAlternativesDecoratorsAndInterceptorsWithPriority(at); } addAdditionalAnnotatedTypes(fireAfterTypeDiscoveryEvent(), globalBdaAnnotatedTypes); // Also configures deployments, interceptors, decorators. deployFromXML(scanner); final Map, ExtendedBeanAttributes>> beanAttributesPerBda = getBeanAttributes(annotatedTypesPerBda); // shouldn't be used anymore, view is now beanAttributes annotatedTypesPerBda.clear(); SpecializationUtil specializationUtil = new SpecializationUtil(webBeansContext); specializationUtil.removeDisabledBeanAttributes(beanAttributesPerBda, null, true); //Checking stereotype conditions checkStereoTypes(scanner); // Handle Specialization specializationUtil.removeDisabledBeanAttributes( beanAttributesPerBda, new SpecializationUtil.BeanAttributesProvider() { @Override public BeanAttributes get(final AnnotatedType at) { ExtendedBeanAttributes data = null; for (Map, ExtendedBeanAttributes> beanAttributes : beanAttributesPerBda.values()) { data = beanAttributes.get(at); if (data != null) { break; } } return data == null ? null : data.beanAttributes; } }, false); // create beans from the discovered AnnotatedTypes deployFromBeanAttributes(beanAttributesPerBda); webBeansContext.getWebBeansUtil().configureProducerMethodSpecializations(); // all beans which got 'overridden' by a Specialized version can be removed now removeDisabledBeans(); // We are finally done with our bean discovery fireAfterBeanDiscoveryEvent(); validateAlternatives(beanAttributesPerBda); validateInjectionPoints(); validateDisposeParameters(); validateDecoratorDecoratedTypes(); validateDecoratorGenericTypes(); webBeansContext.getBeanManagerImpl().getNotificationManager().clearCaches(); // fire event fireAfterDeploymentValidationEvent(); // do some cleanup after the deployment scanner.release(); webBeansContext.getAnnotatedElementFactory().clear(); webBeansContext.getBeanManagerImpl().getInjectionResolver().setStartup(false); } } catch (UnsatisfiedResolutionException e) { throw new WebBeansDeploymentException(e); } catch (AmbiguousResolutionException e) { throw new WebBeansDeploymentException(e); } catch (UnproxyableResolutionException e) { // the tck expects a DeploymentException, but it really should be a DefinitionException, see i.e. https://issues.jboss.org/browse/CDITCK-346 throw new WebBeansDeploymentException(e); } catch (IllegalArgumentException e) { throw new WebBeansConfigurationException(e); } catch (Exception e) { throw ExceptionUtil.throwAsRuntimeException(e); } finally { //if bootstrapping failed, it doesn't make sense to do it again //esp. because #addInternalBean might have been called already and would cause an exception in the next run deployed = true; } } private Map, ExtendedBeanAttributes>> getBeanAttributes( final Map>> annotatedTypesPerBda) { final Map, ExtendedBeanAttributes>> beanAttributesPerBda = new HashMap, ExtendedBeanAttributes>>(); for (Map.Entry>> atEntry : annotatedTypesPerBda.entrySet()) { BeanArchiveInformation bdaInfo = atEntry.getKey(); List> annotatedTypes = atEntry.getValue(); boolean onlyScopedBeans = BeanDiscoveryMode.TRIM.equals(bdaInfo.getBeanDiscoveryMode()); final Map, ExtendedBeanAttributes> bdaBeanAttributes = new IdentityHashMap, ExtendedBeanAttributes>(annotatedTypes.size()); final Iterator> iterator = annotatedTypes.iterator(); while (iterator.hasNext()) { final AnnotatedType at = iterator.next(); final Class beanClass = at.getJavaClass(); final boolean isEjb = discoverEjb && EJBWebBeansConfigurator.isSessionBean(beanClass, webBeansContext); try { if (isEjb || (ClassUtil.isConcrete(beanClass) || WebBeansUtil.isDecorator(at)) && isValidManagedBean(at)) { final BeanAttributesImpl tBeanAttributes = BeanAttributesBuilder.forContext(webBeansContext).newBeanAttibutes(at, onlyScopedBeans).build(); if (tBeanAttributes != null) { final BeanAttributes beanAttributes = webBeansContext.getWebBeansUtil().fireProcessBeanAttributes(at, at.getJavaClass(), tBeanAttributes); if (beanAttributes != null) { bdaBeanAttributes.put(at, new ExtendedBeanAttributes(beanAttributes, isEjb)); } } } else { iterator.remove(); } } catch (final NoClassDefFoundError ncdfe) { logger.info("Skipping deployment of Class " + beanClass + "due to a NoClassDefFoundError: " + ncdfe.getMessage()); } } beanAttributesPerBda.put(bdaInfo, bdaBeanAttributes); } return beanAttributesPerBda; } private void validateDisposeParameters() { final WebBeansUtil webBeansUtil = webBeansContext.getWebBeansUtil(); for (final Bean bean : webBeansContext.getBeanManagerImpl().getBeans()) { if (ProducerMethodBean.class.isInstance(bean)) { final Producer producer = AbstractProducerBean.class.cast(bean).getProducer(); if (BaseProducerProducer.class.isInstance(producer)) { final BaseProducerProducer producerProducer = BaseProducerProducer.class.cast(producer); final Set disposalIPs = producerProducer.getDisposalIPs(); if (disposalIPs != null && !producerProducer.isAnyDisposal()) // any can be ambiguous but that's not an issue { webBeansUtil.validate(disposalIPs, bean); } } } } } /** * @throws DefinitionException if {@link javax.enterprise.inject.spi.Decorator#getDecoratedTypes()} isEmpty */ private void validateDecoratorDecoratedTypes() { for (Decorator decorator : decoratorsManager.getDecorators()) { if (decorator.getDecoratedTypes().isEmpty()) { throw new WebBeansConfigurationException("Decorator must implement at least one interface (java.io.Serializeable will be ignored)"); } } } // avoid delegate implementing Foo and decorator implementing Foo with no link between A and B private void validateDecoratorGenericTypes() { for (final Decorator decorator : decoratorsManager.getDecorators()) { final Type type = decorator.getDelegateType(); // capture ParameterizedType from decorator type final Collection types = new HashSet(); if (Class.class.isInstance(type)) { Class c = Class.class.cast(type); while (c != Object.class && c != null) { types.add(c); for (final Type t : asList(c.getGenericInterfaces())) { if (ParameterizedType.class.isInstance(t)) { types.add(t); } } final Type genericSuperclass = c.getGenericSuperclass(); if (ParameterizedType.class.isInstance(genericSuperclass)) { types.add(genericSuperclass); } c = c.getSuperclass(); } } // else? // check arguments matches with decorator API for (final Type api : decorator.getTypes()) { if (!ParameterizedType.class.isInstance(api)) // no need to check here { continue; } final ParameterizedType pt1 = ParameterizedType.class.cast(api); for (final Type t : types) { if (ParameterizedType.class.isInstance(t)) { final ParameterizedType pt2 = ParameterizedType.class.cast(t); if (pt1.getRawType() == pt2.getRawType() && !GenericsUtil.isAssignableFrom(true, false, pt1, pt2)) { throw new WebBeansConfigurationException("Generic error matching " + api + " and " + t); } } } } } } /** * Remove all beans which are not enabled anymore. * This might e.g. happen because they are 'overridden' * by a @Specialized bean. * We remove those beans now to not having to take care later * during {@link org.apache.webbeans.container.BeanManagerImpl#resolve(java.util.Set)} */ private void removeDisabledBeans() { Iterator> beans = webBeansContext.getBeanManagerImpl().getBeans().iterator(); while(beans.hasNext()) { Bean bean = beans.next(); if (!((OwbBean) bean).isEnabled()) { beans.remove(); } } } private void registerAlternativesDecoratorsAndInterceptorsWithPriority(List> annotatedTypes) { AlternativesManager alternativesManager = webBeansContext.getAlternativesManager(); for (AnnotatedType annotatedType : annotatedTypes) { if (annotatedType.getAnnotation(Alternative.class) != null) { Priority priority = annotatedType.getAnnotation(Priority.class); if (priority != null) { alternativesManager.addPriorityClazzAlternative(annotatedType.getJavaClass(), priority); } } if (annotatedType.getAnnotation(javax.interceptor.Interceptor.class) != null) { Priority priority = annotatedType.getAnnotation(Priority.class); if (priority != null) { final Class javaClass = annotatedType.getJavaClass(); interceptorsManager.addPriorityClazzInterceptor(javaClass, priority); } } if (annotatedType.getAnnotation(javax.decorator.Decorator.class) != null) { Priority priority = annotatedType.getAnnotation(Priority.class); if (priority != null) { final Class javaClass = annotatedType.getJavaClass(); decoratorsManager.addPriorityClazzDecorator(javaClass, priority); } } } } /** * Configure Default Beans. */ private void configureDefaultBeans() { BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl(); WebBeansUtil webBeansUtil = webBeansContext.getWebBeansUtil(); // Register Conversation built-in component beanManager.addInternalBean(webBeansUtil.getConversationBean()); // Register InjectionPoint bean beanManager.addInternalBean(webBeansUtil.getInjectionPointBean()); //Register Instance Bean beanManager.addInternalBean(webBeansUtil.getInstanceBean()); //Register Event Bean beanManager.addInternalBean(webBeansUtil.getEventBean()); beanManager.addInternalBean(webBeansUtil.getEventMetadataBean()); //Register Metadata Beans beanManager.addInternalBean(webBeansUtil.getBeanMetadataBean()); beanManager.addInternalBean(webBeansUtil.getInterceptorMetadataBean()); beanManager.addInternalBean(webBeansUtil.getDecoratorMetadataBean()); beanManager.addInternalBean(webBeansUtil.getInterceptedOrDecoratedBeanMetadataBean()); // Register PrincipalBean beanManager.addInternalBean(webBeansUtil.getPrincipalBean()); //REgister Provider Beans OpenWebBeansJavaEEPlugin beanEeProvider = webBeansContext.getPluginLoader().getJavaEEPlugin(); if(beanEeProvider != null) { beanEeProvider.registerEEBeans(); } } private void addDefaultBean(WebBeansContext ctx,String className) { Bean bean = null; Class beanClass = ClassUtil.getClassFromName(className); if(beanClass != null) { bean = (Bean)newInstance(ctx, beanClass); } if(bean != null) { ctx.getBeanManagerImpl().addInternalBean(bean); } } /** * create a new instance of the class */ private Object newInstance(WebBeansContext wbc, Class clazz) { try { if(System.getSecurityManager() != null) { final Constructor c = webBeansContext.getSecurityService().doPrivilegedGetConstructor(clazz, WebBeansContext.class); if (c == null) { return webBeansContext.getSecurityService().doPrivilegedObjectCreate(clazz); } return c.newInstance(wbc); } if (clazz.getConstructors().length > 0) { try { return clazz.getConstructor(new Class[] { WebBeansContext.class }).newInstance(wbc); } catch (final Exception e) { return clazz.newInstance(); } } return clazz.newInstance(); } catch(Exception e) { Throwable cause = e; if(e instanceof PrivilegedActionException) { cause = e.getCause(); } String error = "Error occurred while creating an instance of class : " + clazz.getName(); logger.log(Level.SEVERE, error, cause); throw new WebBeansException(error,cause); } } /** * Fires event before bean discovery. */ private void fireBeforeBeanDiscoveryEvent() { BeanManagerImpl manager = webBeansContext.getBeanManagerImpl(); BeforeBeanDiscoveryImpl event = new BeforeBeanDiscoveryImpl(webBeansContext); manager.fireLifecycleEvent(event); event.setStarted(); } /** * Fires event after bean discovery. */ private void fireAfterBeanDiscoveryEvent() { BeanManagerImpl manager = webBeansContext.getBeanManagerImpl(); manager.setAfterBeanDiscoveryStart(); final AfterBeanDiscoveryImpl event = new AfterBeanDiscoveryImpl(webBeansContext); manager.fireLifecycleEvent(event); webBeansContext.getWebBeansUtil().inspectDefinitionErrorStack( "There are errors that are added by AfterBeanDiscovery event observers. Look at logs for further details"); manager.setAfterBeanDiscoveryDone(); event.setStarted(); } /** * Fires event after bean discovery. */ private List> fireAfterTypeDiscoveryEvent() { final BeanManagerImpl manager = webBeansContext.getBeanManagerImpl(); final List> newAt = new LinkedList>(); final List> interceptors = interceptorsManager.getPrioritizedInterceptors(); final List> decorators = decoratorsManager.getPrioritizedDecorators(); final List> alternatives = webBeansContext.getAlternativesManager().getPrioritizedAlternatives(); // match AfterTypeDiscovery expected order (1, 2, 3...) Collections.reverse(interceptors); Collections.reverse(decorators); Collections.reverse(alternatives); final AfterTypeDiscoveryImpl event = new AfterTypeDiscoveryImpl(webBeansContext, newAt, interceptors, decorators, alternatives); manager.fireLifecycleEvent(event); // reverse to keep "selection" order - decorator and interceptors considers it in their sorting. // NOTE: from here priorityClass.getSorted() MUST NOT be recomputed (ie no priorityClass.add(...)) Collections.reverse(alternatives); event.setStarted(); // we do not need to set back the sortedAlternatives to the AlternativesManager as the API // and all layers in between use a mutable List. Not very elegant but spec conform. webBeansContext.getWebBeansUtil().inspectDeploymentErrorStack( "There are errors that are added by AfterTypeDiscovery event observers. Look at logs for further details"); return newAt; } /** * Fires event after deployment valdiation. */ private void fireAfterDeploymentValidationEvent() { final BeanManagerImpl manager = webBeansContext.getBeanManagerImpl(); manager.setAfterDeploymentValidationFired(true); final AfterDeploymentValidationImpl event = new AfterDeploymentValidationImpl(manager); manager.fireLifecycleEvent(event); webBeansContext.getWebBeansUtil().inspectDeploymentErrorStack( "There are errors that are added by AfterDeploymentValidation event observers. Look at logs for further details"); packageVetoCache.clear(); // no more needed, free the memory event.setStarted(); } /** * Check if all XML configured alternatives end up as alternative beans * @param beanAttributesPerBda */ private void validateAlternatives(Map, ExtendedBeanAttributes>> beanAttributesPerBda) { Set> xmlConfiguredAlternatives = webBeansContext.getAlternativesManager().getXmlConfiguredAlternatives(); InjectionResolver injectionResolver = webBeansContext.getBeanManagerImpl().getInjectionResolver(); for (Class alternativeClass : xmlConfiguredAlternatives) { if (AnnotationUtil.hasClassAnnotation(alternativeClass, Alternative.class) || AnnotationUtil.hasMetaAnnotation(alternativeClass.getAnnotations(), Alternative.class)) { continue; } boolean foundAlternativeClass = false; Set> beans = injectionResolver.implResolveByType(false, alternativeClass, AnyLiteral.INSTANCE); if (beans == null || beans.isEmpty()) { out: for (Map, ExtendedBeanAttributes> annotatedTypeExtendedBeanAttributesMap : beanAttributesPerBda.values()) { for (Map.Entry, ExtendedBeanAttributes> exType : annotatedTypeExtendedBeanAttributesMap.entrySet()) { if (alternativeClass.equals(exType.getKey().getJavaClass())) { if (exType.getValue().beanAttributes.isAlternative() || exType.getKey().getAnnotation(Alternative.class) != null) { foundAlternativeClass = true; break out; // all fine, continue with the next } } } } } else { for (Bean bean : beans) { if (bean.isAlternative()) { foundAlternativeClass = true; break; } } } if (!foundAlternativeClass) { throw new WebBeansDeploymentException("Given alternative class : " + alternativeClass.getName() + " is not annotated wih @Alternative or not an enabled bean"); } } } /** * Validate all injection points. */ private void validateInjectionPoints() { logger.fine("Validation of injection points has started."); decoratorsManager.validateDecoratorClasses(); interceptorsManager.validateInterceptorClasses(); //Adding decorators to validate Set> decorators = decoratorsManager.getDecorators(); logger.fine("Validation of the decorator's injection points has started."); //Validate Decorators validate(decorators); //Adding interceptors to validate List> interceptors = interceptorsManager.getCdiInterceptors(); logger.fine("Validation of the interceptor's injection points has started."); //Validate Interceptors validate(interceptors); logger.fine("Validation of the beans' injection points has started."); Set> beans = webBeansContext.getBeanManagerImpl().getBeans(); //Validate Others validate(beans); logger.fine("Validation of the observer methods' injection points has started."); //Validate Observers validateObservers(webBeansContext.getBeanManagerImpl().getNotificationManager().getObserverMethods()); logger.info(OWBLogConst.INFO_0003); } /** * Validates beans. * * @param beans deployed beans */ private > void validate(Collection beans) { webBeansContext.getBeanManagerImpl().getInjectionResolver().clearCaches(); if (beans != null && beans.size() > 0) { Stack beanNames = new Stack(); for (Bean bean : beans) { try { if (bean instanceof OwbBean && !((OwbBean) bean).isEnabled()) { // we skip disabled beans continue; } //don't validate the cdi-api if (bean.getBeanClass().getName().startsWith(JAVAX_ENTERPRISE_PACKAGE)) { if (BuiltInOwbBean.class.isInstance(bean)) { final Class proxyable = BuiltInOwbBean.class.cast(bean).proxyableType(); if (proxyable != null) { final AbstractProducer producer = AbstractProducer.class.cast(OwbBean.class.cast(bean).getProducer()); final AnnotatedType annotatedType = webBeansContext.getAnnotatedElementFactory().newAnnotatedType(proxyable); producer.defineInterceptorStack(bean, annotatedType, webBeansContext); } } continue; } String beanName = bean.getName(); if (beanName != null) { beanNames.push(beanName); } if (bean instanceof OwbBean && !(bean instanceof Interceptor) && !(bean instanceof Decorator)) { AbstractProducer producer = null; OwbBean owbBean = (OwbBean) bean; if (ManagedBean.class.isInstance(bean)) // in this case don't use producer which can be wrapped { producer = ManagedBean.class.cast(bean).getOriginalInjectionTarget(); } if (producer == null && owbBean.getProducer() instanceof AbstractProducer) { producer = (AbstractProducer) owbBean.getProducer(); } if (producer != null) { AnnotatedType annotatedType; if (owbBean instanceof InjectionTargetBean) { annotatedType = ((InjectionTargetBean) owbBean).getAnnotatedType(); } else { annotatedType = webBeansContext.getAnnotatedElementFactory().newAnnotatedType(owbBean.getReturnType()); } producer.defineInterceptorStack(owbBean, annotatedType, webBeansContext); } } //Bean injection points Set injectionPoints = bean.getInjectionPoints(); //Check injection points if (injectionPoints != null) { webBeansContext.getWebBeansUtil().validate(injectionPoints, bean); } //Check passivation scope checkPassivationScope(bean); } catch (RuntimeException e) { throw ExceptionUtil.addInformation(e, "Problem while validating bean " + bean); } } //Validate Bean names validateBeanNames(beanNames); //Clear Names beanNames.clear(); } } private void validateObservers(Collection> observerMethods) { for (ObserverMethod observerMethod: observerMethods) { if (observerMethod instanceof OwbObserverMethod) { OwbObserverMethod owbObserverMethod = (OwbObserverMethod)observerMethod; webBeansContext.getWebBeansUtil().validate(owbObserverMethod.getInjectionPoints(), null); } } } private void validateBeanNames(Stack beanNames) { if(beanNames.size() > 0) { for(String beanName : beanNames) { for(String other : beanNames) { String part = null; int i = beanName.lastIndexOf('.'); if(i != -1) { part = beanName.substring(0,i); } if(beanName.equals(other)) { InjectionResolver resolver = webBeansContext.getBeanManagerImpl().getInjectionResolver(); Set> beans = resolver.implResolveByName(beanName); if(beans.size() > 1) { try { resolver.resolve(beans, null); } catch(AmbiguousResolutionException are) { // throw the Exception with even more information InjectionExceptionUtil.throwAmbiguousResolutionExceptionForBeanName(beans, beanName); } } } else { if(part != null && part.equals(other)) { throw new WebBeansDeploymentException("EL name of one bean is of the form x.y, where y is a valid bean EL name, and " + "x is the EL name of the other bean for the bean name : " + beanName); } } } } } } /** * Create AnnotatedTypes from the ClassPath via the ScannerService */ private Map>> annotatedTypesFromClassPath(ScannerService scanner) { logger.fine("Creating AnnotatedTypes from class files has started."); Set> foundClasses = new HashSet>(100); Map>> annotatedTypesPerBda = new HashMap>>(); if (scanner instanceof BdaScannerService) { Map>> beanClassesPerBda = ((BdaScannerService) scanner).getBeanClassesPerBda(); for (Map.Entry>> bdaEntry : beanClassesPerBda.entrySet()) { BeanArchiveInformation bdaInfo = bdaEntry.getKey(); List> annotatedTypes = annotatedTypesFromBdaClassPath(bdaEntry.getValue(), foundClasses); annotatedTypesPerBda.put(bdaEntry.getKey(), annotatedTypes); } // also add the rest of the class es to the default bda // we also need this initialised in case annotatedTypes get added manually at a later step annotatedTypesPerBda.put(defaultBeanArchiveInformation, annotatedTypesFromBdaClassPath(scanner.getBeanClasses(), foundClasses)); } else { // this path is only for backward compat to older ScannerService implementations Set> classIndex = scanner.getBeanClasses(); List> annotatedTypes = annotatedTypesFromBdaClassPath(classIndex, foundClasses); annotatedTypesPerBda.put(defaultBeanArchiveInformation, annotatedTypes); } return annotatedTypesPerBda; } /** * @param foundClasses classes which already got processed. To prevent picking up the same class from multiple classpaths */ private List> annotatedTypesFromBdaClassPath(Set> classIndex, Set> foundClasses) { List> annotatedTypes = new ArrayList>(); //Iterating over each class if (classIndex != null) { AnnotatedElementFactory annotatedElementFactory = webBeansContext.getAnnotatedElementFactory(); for (Class implClass : classIndex) { if (foundClasses.contains(implClass)) { // skip this class continue; } foundClasses.add(implClass); if (isVetoed(implClass)) { if (isEEComponent(implClass)) { // fire injection point events and forget AnnotatedType annotatedType = annotatedElementFactory.newAnnotatedType(implClass); InjectionTarget it = webBeansContext.getBeanManagerImpl().createInjectionTarget(annotatedType); for (final InjectionPoint ip : it.getInjectionPoints()) { webBeansContext.getWebBeansUtil().fireProcessInjectionPointEvent(ip); } } continue; } try { //Define annotation type AnnotatedType annotatedType = annotatedElementFactory.getAnnotatedType(implClass); if (annotatedType == null) // mean no annotation created it (normal case) { annotatedType = annotatedElementFactory.newAnnotatedType(implClass); } if (annotatedType == null) { logger.info("Could not create AnnotatedType for class " + implClass); continue; } // Fires ProcessAnnotatedType if (!annotatedType.getJavaClass().isAnnotation()) { GProcessAnnotatedType processAnnotatedEvent = webBeansContext.getWebBeansUtil().fireProcessAnnotatedTypeEvent(annotatedType); if (!processAnnotatedEvent.isVeto()) { annotatedTypes.add(processAnnotatedEvent.getAnnotatedType()); } processAnnotatedEvent.setStarted(); } else { annotatedTypes.add(annotatedType); } } catch (NoClassDefFoundError ncdfe) { logger.info("Skipping deployment of Class " + implClass + "due to a NoClassDefFoundError: " + ncdfe.getMessage()); } } } return annotatedTypes; } private boolean isEEComponent(final Class impl) { OpenWebBeansJavaEEPlugin eePlugin = webBeansContext.getPluginLoader().getJavaEEPlugin(); return eePlugin != null && eePlugin.isEEComponent(impl); } private boolean isVetoed(final Class implClass) { if (implClass.getAnnotation(Vetoed.class) != null) { return true; } ClassLoader classLoader = implClass.getClassLoader(); if (classLoader == null) { classLoader = BeansDeployer.class.getClassLoader(); } Package pckge = implClass.getPackage(); if (pckge == null) { return false; } do { // yes we cache result with potentially different classloader but this is not portable by spec final String name = pckge.getName(); { final Boolean result = packageVetoCache.get(name); if (result != null && result) { return result; } } if (pckge.getAnnotation(Vetoed.class) != null) { packageVetoCache.put(pckge.getName(), true); return true; } else { packageVetoCache.put(pckge.getName(), false); } final int idx = name.lastIndexOf('.'); if (idx > 0) { final String previousPackage = name.substring(0, idx); final Boolean result = packageVetoCache.get(previousPackage); if (result != null && result) { return result; } try // this is related to classloader and not to Package actually :( so we need reflection { pckge = Package.class.cast(GET_PACKAGE.invoke(classLoader, previousPackage)); } catch (final Exception e) { throw new IllegalStateException(e); } } else { pckge = null; } } while (pckge != null); return false; } /** * Process any AnnotatedTypes which got added by BeforeBeanDiscovery#addAnnotatedType * @param annotatedTypes */ private void addAdditionalAnnotatedTypes(Collection> toDeploy, List> annotatedTypes) { for (AnnotatedType annotatedType : toDeploy) { // Fires ProcessAnnotatedType ProcessSyntheticAnnotatedTypeImpl processAnnotatedEvent = !annotatedType.getJavaClass().isAnnotation() ? webBeansContext.getWebBeansUtil().fireProcessSyntheticAnnotatedTypeEvent(annotatedType) : null; if (processAnnotatedEvent == null || !processAnnotatedEvent.isVeto()) { AnnotatedType changedAnnotatedType = processAnnotatedEvent == null ? annotatedType : processAnnotatedEvent.getAnnotatedType(); if (annotatedTypes.contains(changedAnnotatedType)) { annotatedTypes.remove(changedAnnotatedType); } annotatedTypes.add(changedAnnotatedType); } if (processAnnotatedEvent != null) { processAnnotatedEvent.setStarted(); } } } /** * Discovers and deploys classes from class path. * * @param beanAttributesPerBda the AnnotatedTypes which got discovered so far and are not vetoed * @throws ClassNotFoundException if class not found */ protected void deployFromBeanAttributes( Map, ExtendedBeanAttributes>> beanAttributesPerBda) { logger.fine("Deploying configurations from class files has started."); BeanManagerImpl bm = webBeansContext.getBeanManagerImpl(); for (Map, ExtendedBeanAttributes> beanAttributesMap : beanAttributesPerBda.values()) { // Start from the class for (Map.Entry, ExtendedBeanAttributes> annotatedType : beanAttributesMap.entrySet()) { try { deploySingleAnnotatedType(annotatedType.getKey(), annotatedType.getValue(), beanAttributesMap); } catch (NoClassDefFoundError ncdfe) { logger.info("Skipping deployment of Class " + annotatedType.getKey().getJavaClass() + "due to a NoClassDefFoundError: " + ncdfe.getMessage()); } // if the implClass already gets processed as part of the // standard BDA scanning, then we don't need to 'additionally' // deploy it anymore. bm.removeAdditionalAnnotatedType(annotatedType.getKey()); } } logger.fine("Deploying configurations from class files has ended."); } /** * Common helper method used to deploy annotated types discovered through * scanning or during beforeBeanDiscovery. * * @param annotatedTypeData the AnnotatedType representing the bean to be deployed with their already computed data */ private void deploySingleAnnotatedType(AnnotatedType annotatedType, ExtendedBeanAttributes annotatedTypeData, Map, ExtendedBeanAttributes> annotatedTypes) { Class beanClass = annotatedType.getJavaClass(); // EJBs can be defined so test them really before going for a ManagedBean if (annotatedTypeData.isEjb) { logger.log(Level.FINE, "Found Enterprise Bean with class name : [{0}]", beanClass.getName()); defineEnterpriseWebBean((Class) beanClass, annotatedType, annotatedTypeData.beanAttributes); } else { try { if((ClassUtil.isConcrete(beanClass) || WebBeansUtil.isDecorator(annotatedType)) && isValidManagedBean(annotatedType)) { defineManagedBean(annotatedType, annotatedTypeData.beanAttributes, annotatedTypes); } } catch (NoClassDefFoundError ncdfe) { logger.warning("Skipping deployment of Class " + beanClass + " due to a NoClassDefFoundError: " + ncdfe.getMessage()); } } } private boolean isValidManagedBean(final AnnotatedType type) { final Class beanClass = type.getJavaClass(); final WebBeansUtil webBeansUtil = webBeansContext.getWebBeansUtil(); try { webBeansUtil.checkManagedBean(beanClass); } catch (final DefinitionException e) { logger.log(Level.FINE, "skipped deployment of: " + beanClass.getName() + " reason: " + e.getMessage()); logger.log(Level.FINER, "skipped deployment of: " + beanClass.getName() + " details: ", e); return false; } // done separately to be able to swallow the logging when not relevant and avoid to pollute logs try { if (!webBeansUtil.isConstructorOk(type)) { return false; } } catch (final TypeNotPresentException cnfe) { return false; } //we are not allowed to catch possible exceptions thrown by the following method webBeansUtil.checkManagedBeanCondition(beanClass); return true; } /** * Discovers and deploys alternatives, interceptors and decorators from XML. * * @param scanner discovery scanner * * @throws WebBeansDeploymentException if a problem occurs */ protected void deployFromXML(ScannerService scanner) throws WebBeansDeploymentException { logger.fine("Deploying configurations from XML files has started."); Set bdaLocations = scanner.getBeanXmls(); Iterator it = bdaLocations.iterator(); while (it.hasNext()) { URL url = it.next(); logger.fine("OpenWebBeans BeansDeployer configuring: " + url.toExternalForm()); BeanArchiveInformation beanArchiveInformation = beanArchiveService.getBeanArchiveInformation(url); configureDecorators(url, beanArchiveInformation.getDecorators()); configureInterceptors(url, beanArchiveInformation.getInterceptors()); configureAlternatives(url, beanArchiveInformation.getAlternativeClasses(), false); configureAlternatives(url, beanArchiveInformation.getAlternativeStereotypes(), true); configureAllowProxying(url, beanArchiveInformation.getAllowProxyingClasses()); } logger.fine("Deploying configurations from XML has ended successfully."); } private void configureAlternatives(URL bdaLocation, List alternatives, boolean isStereotype) { AlternativesManager manager = webBeansContext.getAlternativesManager(); AnnotatedElementFactory annotatedElementFactory = webBeansContext.getAnnotatedElementFactory(); // the alternatives in this beans.xml // this gets used to detect multiple definitions of the // same alternative in one beans.xml file. Set alternativesInFile = new HashSet(); for (String alternativeName : alternatives) { if (alternativesInFile.contains(alternativeName)) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Given alternative : " + alternativeName + " is already added as @Alternative" ); } alternativesInFile.add(alternativeName); Class clazz = ClassUtil.getClassFromName(alternativeName); if (clazz == null) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Alternative: " + alternativeName + " not found"); } else { if (isStereotype) { manager.addXmlStereoTypeAlternative(clazz); } else { manager.addXmlClazzAlternative(clazz); } } } } private void configureDecorators(URL bdaLocation, List decorators) { Set decoratorsInFile = new HashSet(); for (String decorator : decorators) { Class clazz = ClassUtil.getClassFromName(decorator); if (clazz == null) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Decorator class : " + decorator + " not found"); } else { if ((scannerService.isBDABeansXmlScanningEnabled() && !scannerService.getBDABeansXmlScanner().addDecorator(clazz, bdaLocation.toExternalForm())) || decoratorsInFile.contains(clazz)) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Decorator class : " + decorator + " is already defined"); } decoratorsManager.addEnabledDecorator(clazz); decoratorsInFile.add(clazz); } } } private void configureInterceptors(URL bdaLocation, List interceptors) { // the interceptors in this beans.xml // this gets used to detect multiple definitions of the // same interceptor in one beans.xml file. Set interceptorsInFile = new HashSet(); for (String interceptor : interceptors) { Class clazz = ClassUtil.getClassFromName(interceptor); if (clazz == null) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Interceptor class : " + interceptor + " not found"); } else { Annotation[] classAnnotations; AnnotatedType annotatedType = webBeansContext.getAnnotatedElementFactory().getAnnotatedType(clazz); if (annotatedType == null) { annotatedType = webBeansContext.getAnnotatedElementFactory().newAnnotatedType(clazz); } GProcessAnnotatedType processAnnotatedEvent = webBeansContext.getWebBeansUtil().fireProcessAnnotatedTypeEvent(annotatedType); // if veto() is called if (processAnnotatedEvent.isVeto()) { return; } annotatedType = processAnnotatedEvent.getAnnotatedType(); processAnnotatedEvent.setStarted(); Set annTypeAnnotations = annotatedType.getAnnotations(); if (annTypeAnnotations != null) { classAnnotations = annTypeAnnotations.toArray(new Annotation[annTypeAnnotations.size()]); } else { classAnnotations = new Annotation[0]; } if (AnnotationUtil.hasAnnotation(classAnnotations, javax.interceptor.Interceptor.class) && !webBeansContext.getAnnotationManager().hasInterceptorBindingMetaAnnotation(classAnnotations)) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Interceptor class : " + interceptor + " must have at least one @InterceptorBinding"); } // check if the interceptor got defined twice in this beans.xml if (interceptorsInFile.contains(clazz)) { throw new WebBeansDeploymentException(createConfigurationFailedMessage(bdaLocation) + "Interceptor class : " + interceptor + " already defined in this beans.xml file!"); } interceptorsInFile.add(clazz); boolean isBDAScanningEnabled = scannerService.isBDABeansXmlScanningEnabled(); if ((!isBDAScanningEnabled && interceptorsManager.isInterceptorClassEnabled(clazz)) || (isBDAScanningEnabled && !scannerService.getBDABeansXmlScanner().addInterceptor(clazz, bdaLocation.toExternalForm()))) { logger.warning( "Interceptor class : " + interceptor + " is already defined"); } else { interceptorsManager.addEnabledInterceptorClass(clazz); } } } } private void configureAllowProxying(URL url, List allowProxyingClasses) { OpenWebBeansConfiguration owbConfiguration = webBeansContext.getOpenWebBeansConfiguration(); for (String allowProxyingClass : allowProxyingClasses) { owbConfiguration.addConfigListValue(OpenWebBeansConfiguration.ALLOW_PROXYING_PARAM, allowProxyingClass); } } /** * Gets error message for XML parsing of the current XML file. * * @return the error messages */ private String createConfigurationFailedMessage(URL bdaLocation) { return "WebBeans configuration defined in " + bdaLocation.toExternalForm() + " did fail. Reason is : "; } /** * Check passivations. */ protected void checkPassivationScope(Bean beanObj) { boolean validate = false; if(beanObj instanceof EnterpriseBeanMarker) { EnterpriseBeanMarker marker = (EnterpriseBeanMarker)beanObj; if(marker.isPassivationCapable()) { validate = true; } } else if(webBeansContext.getBeanManagerImpl().isPassivatingScope(beanObj.getScope())) { if(WebBeansUtil.getPassivationId(beanObj) == null) { if(!(beanObj instanceof AbstractProducerBean)) { throw new WebBeansDeploymentException("Passivation scoped defined bean must be passivation capable, " + "but bean : " + beanObj.toString() + " is not passivation capable"); } } validate = true; } if(validate) { webBeansContext.getDeploymentValidationService().validatePassivationCapable((OwbBean)beanObj); } } /** * Check steretypes. * @param scanner scanner instance */ protected void checkStereoTypes(ScannerService scanner) { logger.fine("Checking StereoType constraints has started."); addDefaultStereoTypes(); final AnnotationManager annotationManager = webBeansContext.getAnnotationManager(); Set> beanClasses = scanner.getBeanClasses(); if (beanClasses != null && beanClasses.size() > 0) { final StereoTypeManager stereoTypeManager = webBeansContext.getStereoTypeManager(); for(Class beanClass : beanClasses) { if(beanClass.isAnnotation()) { Class stereoClass = (Class) beanClass; if (annotationManager.isStereoTypeAnnotation(stereoClass) && stereoTypeManager.getStereoTypeModel(stereoClass.getName()) == null) { webBeansContext.getAnnotationManager().checkStereoTypeClass(stereoClass, stereoClass.getDeclaredAnnotations()); StereoTypeModel model = new StereoTypeModel(webBeansContext, stereoClass); stereoTypeManager.addStereoTypeModel(model); } } } } logger.fine("Checking StereoType constraints has ended."); } /** * Adds default stereotypes. */ protected void addDefaultStereoTypes() { StereoTypeModel model = new StereoTypeModel(webBeansContext, Model.class); webBeansContext.getStereoTypeManager().addStereoTypeModel(model); } /** * Defines and configures managed bean. * @param type info */ protected void defineManagedBean(AnnotatedType annotatedType, BeanAttributes attributes, Map, ExtendedBeanAttributes> annotatedTypes) { //Fires ProcessInjectionTarget event for Java EE components instances //That supports injections but not managed beans Class beanClass = annotatedType.getJavaClass(); if(webBeansContext.getWebBeansUtil().supportsJavaEeComponentInjections(beanClass)) { //Fires ProcessInjectionTarget webBeansContext.getWebBeansUtil().fireProcessInjectionTargetEventForJavaEeComponents(beanClass).setStarted(); webBeansContext.getWebBeansUtil().inspectDeploymentErrorStack( "There are errors that are added by ProcessInjectionTarget event observers. Look at logs for further details"); //Checks that not contains @Inject InjectionPoint webBeansContext.getAnnotationManager().checkInjectionPointForInjectInjectionPoint(beanClass); } { ManagedBeanBuilder> managedBeanCreator = new ManagedBeanBuilder>(webBeansContext, annotatedType, attributes); if(WebBeansUtil.isDecorator(annotatedType)) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Found Managed Bean Decorator with class name : [{0}]", annotatedType.getJavaClass().getName()); } DecoratorBeanBuilder dbb = new DecoratorBeanBuilder(webBeansContext, annotatedType, attributes); if (dbb.isDecoratorEnabled()) { dbb.defineDecoratorRules(); DecoratorBean decorator = dbb.getBean(); decoratorsManager.addDecorator(decorator); } } else if(WebBeansUtil.isCdiInterceptor(annotatedType)) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Found Managed Bean Interceptor with class name : [{0}]", annotatedType.getJavaClass().getName()); } CdiInterceptorBeanBuilder ibb = new CdiInterceptorBeanBuilder(webBeansContext, annotatedType, attributes); if (ibb.isInterceptorEnabled()) { ibb.defineCdiInterceptorRules(); CdiInterceptorBean interceptor = ibb.getBean(); interceptorsManager.addCdiInterceptor(interceptor); } } else { InjectionTargetBean bean = managedBeanCreator.getBean(); if (decoratorsManager.containsCustomDecoratorClass(annotatedType.getJavaClass()) || interceptorsManager.containsCustomInterceptorClass(annotatedType.getJavaClass())) { return; //TODO discuss this case (it was ignored before) } if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Found Managed Bean with class name : [{0}]", annotatedType.getJavaClass().getName()); } final Set> observerMethods; final AnnotatedType beanAnnotatedType = bean.getAnnotatedType(); final AnnotatedType defaultAt = webBeansContext.getAnnotatedElementFactory().getAnnotatedType(beanAnnotatedType.getJavaClass()); final boolean ignoreProducer = defaultAt != beanAnnotatedType && annotatedTypes.containsKey(defaultAt); if(bean.isEnabled()) { observerMethods = new ObserverMethodsBuilder(webBeansContext, beanAnnotatedType).defineObserverMethods(bean); } else { observerMethods = new HashSet>(); } final WebBeansContext wbc = bean.getWebBeansContext(); Set> producerFields = ignoreProducer ? Collections.emptySet() : new ProducerFieldBeansBuilder(wbc, beanAnnotatedType).defineProducerFields(bean); Set> producerMethods = ignoreProducer ? Collections.emptySet() : new ProducerMethodBeansBuilder(wbc, beanAnnotatedType).defineProducerMethods(bean, producerFields); ManagedBean managedBean = (ManagedBean)bean; Map,AnnotatedMethod> annotatedMethods = new HashMap, AnnotatedMethod>(); if (!producerFields.isEmpty() || !producerMethods.isEmpty()) { final Priority priority = annotatedType.getAnnotation(Priority.class); if (priority != null && !webBeansContext.getAlternativesManager() .isAlternative(annotatedType.getJavaClass(), Collections.>emptySet())) { webBeansContext.getAlternativesManager().addPriorityClazzAlternative(annotatedType.getJavaClass(), priority); } } for(ProducerMethodBean producerMethod : producerMethods) { AnnotatedMethod method = webBeansContext.getAnnotatedElementFactory().newAnnotatedMethod(producerMethod.getCreatorMethod(), annotatedType); webBeansContext.getWebBeansUtil().inspectDeploymentErrorStack("There are errors that are added by ProcessProducer event observers for " + "ProducerMethods. Look at logs for further details"); annotatedMethods.put(producerMethod, method); } Map,AnnotatedField> annotatedFields = new HashMap, AnnotatedField>(); for(ProducerFieldBean producerField : producerFields) { webBeansContext.getWebBeansUtil().inspectDeploymentErrorStack("There are errors that are added by ProcessProducer event observers for" + " ProducerFields. Look at logs for further details"); annotatedFields.put(producerField, webBeansContext.getAnnotatedElementFactory().newAnnotatedField( producerField.getCreatorField(), webBeansContext.getAnnotatedElementFactory().newAnnotatedType(producerField.getBeanClass()))); } Map,AnnotatedMethod> observerMethodsMap = new HashMap, AnnotatedMethod>(); for(ObserverMethod observerMethod : observerMethods) { ObserverMethodImpl impl = (ObserverMethodImpl)observerMethod; AnnotatedMethod method = impl.getObserverMethod(); observerMethodsMap.put(observerMethod, method); } BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl(); //Fires ProcessManagedBean ProcessBeanImpl processBeanEvent = new GProcessManagedBean(managedBean, annotatedType); beanManager.fireEvent(processBeanEvent, true); processBeanEvent.setStarted(); webBeansContext.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessManagedBean event observers for " + "managed beans. Look at logs for further details"); //Fires ProcessProducerMethod webBeansContext.getWebBeansUtil().fireProcessProducerMethodBeanEvent(annotatedMethods, annotatedType); webBeansContext.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessProducerMethod event observers for " + "producer method beans. Look at logs for further details"); //Fires ProcessProducerField webBeansContext.getWebBeansUtil().fireProcessProducerFieldBeanEvent(annotatedFields); webBeansContext.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessProducerField event observers for " + "producer field beans. Look at logs for further details"); //Fire ObservableMethods webBeansContext.getWebBeansUtil().fireProcessObservableMethodBeanEvent(observerMethodsMap); webBeansContext.getWebBeansUtil().inspectDefinitionErrorStack("There are errors that are added by ProcessObserverMethod event observers for " + "observer methods. Look at logs for further details"); if(!webBeansContext.getWebBeansUtil().isAnnotatedTypeDecoratorOrInterceptor(annotatedType)) { beanManager.addBean(bean); for (ProducerMethodBean producerMethod : producerMethods) { // add them one after the other to enable serialization handling et al beanManager.addBean(producerMethod); } for (ProducerFieldBean producerField : producerFields) { // add them one after the other to enable serialization handling et al beanManager.addBean(producerField); } } } } } /** * Defines enterprise bean via plugin. * @param bean class type * @param clazz bean class */ protected void defineEnterpriseWebBean(Class clazz, AnnotatedType annotatedType, BeanAttributes attributes) { InjectionTargetBean bean = (InjectionTargetBean) EJBWebBeansConfigurator.defineEjbBean( clazz, annotatedType, attributes, webBeansContext); webBeansContext.getWebBeansUtil().setInjectionTargetBeanEnableFlag(bean); } public static class ExtendedBeanAttributes { private final BeanAttributes beanAttributes; private final boolean isEjb; public ExtendedBeanAttributes(final BeanAttributes beanAttributes, final boolean isEjb) { this.beanAttributes = beanAttributes; this.isEjb = isEjb; } } }