Chapter 11. Portable extensions

A portable extension may integrate with the container by:

11.1. The Bean interface

The interface javax.enterprise.inject.spi.Bean defines everything the container needs to manage instances of a certain bean.

public interface Bean<T> extends Contextual<T> {
    public Set<Type> getTypes();
    public Set<Annotation> getQualifiers();
    public Class<? extends Annotation> getScope();
    public String getName();
    public Set<Class<? extends Annotation>> getStereotypes();
    public Class<?> getBeanClass();
    public boolean isAlternative();
    public boolean isNullable();
    public Set<InjectionPoint> getInjectionPoints();
}

Note that implementations of Bean must also implement the inherited operations defined by the Contextual interface defined in Section 6.1, “The Contextual interface”.

  • getTypes(), getQualifiers(), getScope(), getName() and getStereotypes() must return the bean types, qualifiers, scope type, EL name and stereotypes of the bean, as defined in Chapter 2, Concepts.

  • getBeanClass() returns the bean class of the managed bean or session bean or of the bean that declares the producer method or field.

  • isAlternative() must return true if the bean is an alternative, and false otherwise.

  • isNullable() must return true if the method create() sometimes returns a null value, and false otherwise, as defined in Section 5.2.4, “Primitive types and null values”.

  • getInjectionPoints() returns a set of InjectionPoint objects, defined in Section 5.5.7, “Injection point metadata”, representing injection points of the bean, that will be validated by the container at initialization time.

An instance of Bean exists for every enabled bean.

A portable extension may add support for new kinds of beans beyond those defined by the this specification (managed beans, session beans, producer methods, producer fields and resources) by implementing Bean and registering beans with the container, using the mechanism defined in Section 11.5.2, “AfterBeanDiscovery event”.

11.1.1. The Decorator interface

The Bean object for a decorator must implement the interface javax.enterprise.inject.spi.Decorator.

public interface Decorator<T> extends Bean<T> {
    public Set<Type> getDecoratedTypes();
    public Type getDelegateType();
    public Set<Annotation> getDelegateQualifiers();
}
  • getDecoratedTypes() returns the decorated types of the decorator.

  • getDelegateType() and getDelegateQualifiers() return the delegate type and qualifiers of the decorator.

An instance of Decorator exists for every enabled decorator.

11.1.2. The Interceptor interface

The Bean object for an interceptor must implement javax.enterprise.inject.spi.Interceptor.

public interface Interceptor<T> extends Bean<T> {
    public Set<Annotation> getInterceptorBindings();
    public boolean intercepts(InterceptionType type);
    public Object intercept(InterceptionType type, T instance, InvocationContext ctx);
}
  • getInterceptorBindings() returns the interceptor bindings of the interceptor.

  • intercepts() returns true if the interceptor intercepts the specified kind of lifecycle callback or method invocation, and false otherwise.

  • intercept() invokes the specified kind of lifecycle callback or method invocation interception upon the given instance of the interceptor.

An InterceptionType identifies the kind of lifecycle callback, EJB timeout method or business method.

public enum InterceptionType { 
    AROUND_INVOKE, POST_CONSTRUCT, PRE_DESTROY, PRE_PASSIVATE, POST_ACTIVATE, AROUND_TIMEOUT
}

An instance of Interceptor exists for every enabled interceptor.

11.1.3. The ObserverMethod interface

The interface javax.enterprise.inject.spi.ObserverMethod defines everything the container needs to know about an observer method.

public interface ObserverMethod<T> {
    public Class<?> getBeanClass();
    public Type getObservedType();
    public Set<Annotation> getObservedQualifiers();
    public Reception getReception();
    public TransactionPhase getTransactionPhase();
    public void notify(T event);
}
  • getBeanClass() returns the bean class of the bean that declares the observer method.

  • getObservedType() and getObservedQualifiers() return the observed event type and qualifiers.

  • getReception() returns IF_EXISTS for a conditional observer and ALWAYS otherwise.

  • getTransactionPhase() returns the appropriate transaction phase for a transactional observer method or IN_PROGRESS otherwise.

  • notify() calls the observer method, as defined in Section 5.5.6, “Invocation of observer methods”.

An instance of ObserverMethod exists for every observer method of every enabled bean.

11.2. The Producer and InjectionTarget interfaces

The interface javax.enterprise.inject.spi.Producer provides a generic operation for producing an instance of a type.

public interface Producer<T> {
    public T produce(CreationalContext<T> ctx);
    public void dispose(T instance);
    public Set<InjectionPoint> getInjectionPoints();
}

For a Producer that represents a class:

  • produce() calls the constructor annotated @Inject if it exists, or the constructor with no parameters otherwise, as defined in Section 5.5.1, “Injection using the bean constructor”, and returns the resulting instance. If the class has interceptors, produce() is responsible for building the interceptors and decorators of the instance.

  • dispose() does nothing.

  • getInjectionPoints() returns the set of InjectionPoint objects representing all injected fields, bean constructor parameters and initializer method parameters.

For a Producer that represents a producer method or field:

The subinterface javax.enterprise.inject.spi.InjectionTarget provides operations for performing dependency injection and lifecycle callbacks on an instance of a type.

public interface InjectionTarget<T> {
        extends Producer<T>
    public void inject(T instance, CreationalContext<T> ctx);
    public void postConstruct(T instance);
    public void preDestroy(T instance);
}
  • inject() performs dependency injection upon the given object. The container performs Java EE component environment injection, according to the semantics required by the Java EE platform specification, sets the value of all injected fields, and calls all initializer methods, as defined in Section 5.5.2, “Injection of fields and initializer methods”.

  • postConstruct() calls the @PostConstruct callback, if it exists, according to the semantics required by the Java EE platform specification.

  • preDestroy() calls the @PreDestroy callback, if it exists, according to the semantics required by the Java EE platform specification.

11.3. The BeanManager object

Portable extensions sometimes interact directly with the container via programmatic API call. The interface javax.enterprise.inject.spi.BeanManager provides operations for obtaining contextual references for beans, along with many other operations of use to portable extensions.

The container provides a built-in bean with bean type BeanManager, scope @Dependent and qualifier @Default. The built-in implementation must be a passivation capable dependency, as defined in Section 6.6.2, “Passivation capable dependencies”. Thus, any bean may obtain an instance of BeanManager by injecting it:

@Inject BeanManager manager;

Java EE components may obtain an instance of BeanManager from JNDI by looking up the name java:comp/BeanManager.

Any operation of BeanManager may be called at any time during the execution of the application.

11.3.1. Obtaining a contextual reference for a bean

The method BeanManager.getReference() returns a contextual reference for a given bean and bean type, as defined in Section 6.5.3, “Contextual reference for a bean”.

public Object getReference(Bean<?> bean, Type beanType, CreationalContext<?> ctx);

The first parameter is the Bean object representing the bean. The second parameter represents a bean type that must be implemented by any client proxy that is returned. The third parameter is an instance of CreationalContext that may be used to destroy any object with scope @Dependent that is created.

If the given type is not a bean type of the given bean, an IllegalArgumentException is thrown.

11.3.2. Obtaining an injectable reference

The method BeanManager.getInjectableReference() returns an injectable reference for a given injection point, as defined in Section 6.5.5, “Injectable references”.

public Object getInjectableReference(InjectionPoint ij, CreationalContext<?> ctx);

The first parameter represents the target injection point. The second parameter is an instance of CreationalContext that may be used to destroy any object with scope @Dependent that is created.

If the InjectionPoint represents a decorator delegate injection point, getInjectableReference() returns a delegate, as defined in Section 8.1.2, “Decorator delegate injection points”.

If typesafe resolution results in an unsatisfied dependency, the container must throw an UnsatisfiedResolutionException. If typesafe resolution results in an unresolvable ambiguous dependency, the container must throw an AmbiguousResolutionException.

Implementations of Bean usually maintain a reference to an instance of BeanManager. When the Bean implementation performs dependency injection, it must obtain the contextual instances to inject by calling BeanManager.getInjectableReference(), passing an instance of InjectionPoint that represents the injection point and the instance of CreationalContext that was passed to Bean.create().

11.3.3. Obtaining a CreationalContext

An instance of CreationalContext for a certain instance of Contextual may be obtained by calling BeanManager.createCreationalContext().

public <T> CreationalContext<T> createCreationalContext(Contextual<T> contextual);

An instance of CreationalContext for a non-contextual object may be obtained by passing a null value to createCreationalContext().

11.3.4. Obtaining a Bean by type

The method BeanManager.getBeans() returns the set of beans which have the given required type and qualifiers and are available for injection in the module or library containing the class into which the BeanManager was injected or the Java EE component from whose JNDI environment namespace the BeanManager was obtained, according to the rules of typesafe resolution defined in Section 5.2, “Typesafe resolution”.

public Set<Bean<?>> getBeans(Type beanType, Annotation... qualifiers);

The first parameter is a required bean type. The remaining parameters are required qualifiers.

If no qualifiers are passed to getBeans(), the default qualifier @Default is assumed.

If the given type represents a type variable, an IllegalArgumentException is thrown.

If two instances of the same qualifier type are given, an IllegalArgumentException is thrown.

If an instance of an annotation that is not a qualifier type is given, an IllegalArgumentException is thrown.

11.3.5. Obtaining a Bean by name

The method BeanManager.getBeans() which accepts a string returns the set of beans which have the given EL name and are available for injection in the module or library containing the class into which the BeanManager was injected or the Java EE component from whose JNDI environment namespace the BeanManager was obtained, according to the rules of EL name resolution defined in Section 5.3, “EL name resolution”.

public Set<Bean<?>> getBeans(String name);

The parameter is an EL name.

11.3.6. Obtaining a passivation capable bean by identifier

The method BeanManager.getPassivationCapableBean() returns the PassivationCapable bean with the given identifier (see Section 6.6.1, “Passivation capable beans”).

public Bean<?> getPassivationCapableBean(String id);

11.3.7. Resolving an ambiguous dependency

The method BeanManager.resolve() applies the ambiguous dependency resolution rules defined in Section 5.2.1, “Unsatisfied and ambiguous dependencies” to a set of Beans.

public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans);

If the ambiguous dependency resolution rules fail, the container must throw an AmbiguousResolutionException.

11.3.8. Validating an injection point

The BeanManager.validate() operation validates an injection point and throws an InjectionException if there is a deployment problem (for example, an unsatisfied or unresolvable ambiguous dependency) associated with the injection point.

public void validate(InjectionPoint injectionPoint);

11.3.9. Firing an event

The method BeanManager.fireEvent() fires an event and notifies observers, according to Section 10.5, “Observer notification”.

public void fireEvent(Object event, Annotation... qualifiers);

The first argument is the event object. The remaining parameters are event qualifiers.

If the runtime type of the event object contains a type variable, an IllegalArgumentException is thrown.

If two instances of the same qualifier type are given, an IllegalArgumentException is thrown.

If an instance of an annotation that is not a qualifier type is given, an IllegalArgumentException is thrown.

11.3.10. Observer method resolution

The method BeanManager.resolveObserverMethods() resolves observer methods for an event according to the rules of observer resolution defined in Section 10.2, “Observer resolution”.

public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... qualifiers);

The first parameter of resolveObserverMethods() is the event object. The remaining parameters are event qualifiers.

If the runtime type of the event object contains a type variable, an IllegalArgumentException is thrown.

If two instances of the same qualifier type are given, an IllegalArgumentException is thrown.

If an instance of an annotation that is not a qualifier type is given, an IllegalArgumentException is thrown.

11.3.11. Decorator resolution

The method BeanManager.resolveDecorators() returns the ordered list of decorators for a set of bean types and a set of qualifiers and which are enabled in the module or library containing the class into which the BeanManager was injected or the Java EE component from whose JNDI environment namespace the BeanManager was obtained, as defined in Section 8.3, “Decorator resolution”.

List<Decorator<?>> resolveDecorators(Set<Type> types, Annotation... qualifiers);

The first argument is the set of bean types of the decorated bean. The annotations are qualifiers declared by the decorated bean.

If two instances of the same qualifier type are given, an IllegalArgumentException is thrown.

If an instance of an annotation that is not a qualifier type is given, an IllegalArgumentException is thrown.

If the set of bean types is empty, an IllegalArgumentException is thrown.

11.3.12. Interceptor resolution

The method BeanManager.resolveInterceptors() returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the BeanManager was injected or the Java EE component from whose JNDI environment namespace the BeanManager was obtained, as defined in Section 9.5, “Interceptor resolution”.

List<Interceptor<?>> resolveInterceptors(InterceptionType type, 
                                         Annotation... interceptorBindings);

If two instances of the same interceptor binding type are given, an IllegalArgumentException is thrown.

If no interceptor binding type instance is given, an IllegalArgumentException is thrown.

If an instance of an annotation that is not an interceptor binding type is given, an IllegalArgumentException is thrown.

11.3.13. Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type

A portable extension may test an annotation to determine if it is a qualifier type, scope type, stereotype or interceptor binding type, obtain the set of meta-annotations declared by a stereotype or interceptor binding type, or determine if a scope type is a normal or passivating scope.

public boolean isScope(Class<? extends Annotation> annotationType);
public boolean isQualifier(Class<? extends Annotation> annotationType);
public boolean isInterceptorBinding(Class<? extends Annotation> annotationType);
public boolean isStereotype(Class<? extends Annotation> annotationType);
    
public boolean isNormalScope(Class<? extends Annotation> scopeType);
public boolean isPassivatingScope(Class<? extends Annotation> scopeType);
public Set<Annotation> getInterceptorBindingDefinition(Class<? extends Annotation> qualifierType);
public Set<Annotation> getStereotypeDefinition(Class<? extends Annotation> stereotype);

11.3.14. Obtaining the active Context for a scope

The method BeanManager.getContext() retrieves an active context object associated with the a given scope, as defined in Section 6.5.1, “The active context object for a scope”.

public Context getContext(Class<? extends Annotation> scopeType);

11.3.15. Obtaining the ELResolver

The method BeanManager.getELResolver() returns the javax.el.ELResolver specified in Section 12.4, “Integration with Unified EL”.

public ELResolver getELResolver();

11.3.16. Wrapping a Unified EL ExpressionFactory

The method BeanManager.wrapExpressionFactory() returns a wrapper javax.el.ExpressionFactory that delegates MethodExpression and ValueExpression creation to the given ExpressionFactory. When a Unified EL expression is evaluated using a MethodExpression or ValueExpression returned by the wrapper ExpressionFactory, the rules defined in Section 6.4.3, “Dependent pseudo-scope and Unified EL” are enforced by the container.

public ExpressionFactory wrapExpressionFactory(ExpressionFactory expressionFactory);

11.3.17. Obtaining an AnnotatedType for a class

The method BeanManager.createAnnotatedType() returns an AnnotatedType that may be used to read the annotations of a given Java class or interface.

public <T> AnnotatedType<T> createAnnotatedType(Class<T> type);

11.3.18. Obtaining an InjectionTarget

The method BeanManager.createInjectionTarget() returns a container provided implementation of InjectionTarget for a given AnnotatedType or throws an IllegalArgumentException if there is a definition error associated with any injection point of the type.

public <T> InjectionTarget<T> createInjectionTarget(AnnotatedType<T> type);

11.4. Alternative metadata sources

A portable extension may provide an alternative metadata source, such as configuration by XML.

The interfaces AnnotatedType, AnnotatedField, AnnotatedMethod, AnnotatedConstructor and AnnotatedParameter in the package javax.enterprise.inject.spi allow a portable extension to specify metadata that overrides the annotations that exist on a bean class. The portable extension is responsible for implementing the interfaces, thereby exposing the metadata to the container.

public interface AnnotatedType<X>
        extends Annotated {
    public Class<X> getJavaClass();
    public Set<AnnotatedConstructor<X>> getConstructors();
    public Set<AnnotatedMethod<? super X>> getMethods();
    public Set<AnnotatedField<? super X>> getFields();
}
public interface AnnotatedField<X> 
        extends AnnotatedMember<X> {    
    public Field getJavaMember();
}
public interface AnnotatedMethod<X> 
        extends AnnotatedCallable<X> {
    public Method getJavaMember();
}
public interface AnnotatedConstructor<X> 
        extends AnnotatedCallable<X> {
    public Constructor<X> getJavaMember();
}
public interface AnnotatedParameter<X> 
        extends Annotated {
    public int getPosition();
    public AnnotatedCallable<X> getDeclaringCallable();
}
public interface AnnotatedMember<X> 
        extends Annotated {
    public Member getJavaMember();
    public boolean isStatic();
    public AnnotatedType<X> getDeclaringType();
}
public interface AnnotatedCallable<X> 
        extends AnnotatedMember<X> {
    public List<AnnotatedParameter<X>> getParameters();
}

The interface javax.enterprise.inject.spi.Annotated exposes the overriding annotations and type declarations.

public interface Annotated {
    public Type getBaseType();
    public Set<Type> getTypeClosure();
    public <T extends Annotation> T getAnnotation(Class<T> annotationType); 
    public Set<Annotation> getAnnotations(); 
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType);
}
  • getBaseType() returns the type of the program element.

  • getTypeClosure() returns all types to which the base type should be considered assignable.

  • getAnnotation() returns the program element annotation of the given annotation type, or a null value.

  • getAnnotations() returns all annotations of the program element.

  • isAnnotationPresent() returns true if the program element has an annotation of the given annotation type, or false otherwise.

The container must use the operations of Annotated and its subinterfaces to discover program element types and annotations, instead of directly calling the Java Reflection API. In particular, the container must:

  • call Annotated.getBaseType() to determine the type of an injection point, event parameter or disposed parameter,

  • call Annotated.getTypeClosure() to determine the bean types of any kind of bean,

  • call Annotated.getAnnotations() to determine the scope, qualifiers, stereotypes and interceptor bindings of a bean,

  • call Annotated.isAnnotationPresent() and Annotated.getAnnotation() to read any bean annotations defined by this specification, and

  • call AnnotatedType.getConstructors(), AnnotatedType.getMethods() and AnnotatedType.getFields() to determine the members of a bean class.

11.5. Container lifecycle events

During the application initialization process, the container fires a series of events, allowing portable extensions to integrate with the container initialization process defined in Section 12.2, “Application initialization lifecycle”.

Observer methods of these events must belong to extensions. An extension is a service provider of the service javax.enterprise.inject.spi.Extension declared in META-INF/services.

public interface Extension {}

Service providers may have observer methods, which may observe any event, including any container lifecycle event, and obtain an injected BeanManager reference.

The container instantiates a single instance of each extension at the beginning of the application initialization process and maintains a reference to it until the application shuts down. The container delivers event notifications to this instance by calling its observer methods.

For each service provider, the container must provide a bean of scope @ApplicationScoped and qualifier @Default, supporting injection of a reference to the service provider instance. The bean types of this bean include the class of the service provider and all superclasses and interfaces.

11.5.1. BeforeBeanDiscovery event

The container must fire an event before it begins the bean discovery process. The event object must be of type javax.enterprise.inject.spi.BeforeBeanDiscovery:

public interface BeforeBeanDiscovery {
    public void addQualifier(Class<? extends Annotation> qualifier);
    public void addScope(Class<? extends Annotation> scopeType, boolean normal, boolean passivating);
    public void addStereotype(Class<? extends Annotation> stereotype, Annotation... stereotypeDef);
    public void addInterceptorBinding(Class<? extends Annotation> bindingType, Annotation... bindingTypeDef);
    public void addAnnotatedType(AnnotatedType<?> type);
}
  • addQualifier() declares an annotation type as a qualifier type.

  • addScope() declares an annotation type as a scope type.

  • addStereotype() declares an annotation type as a stereotype, and specifies its meta-annotations.

  • addInterceptorBinding() declares an annotation type as an interceptor binding type, and specifies its meta-annotations.

  • addAnnotatedType() adds a given AnnotatedType to the set of types which will be scanned during bean discovery.

void beforeBeanDiscovery(@Observes BeforeBeanDiscovery event) { ... }

If any observer method of the BeforeBeanDiscovery event throws an exception, the exception is treated as a definition error by the container.

11.5.2. AfterBeanDiscovery event

The container must fire a second event when it has fully completed the bean discovery process, validated that there are no definition errors relating to the discovered beans, and registered Bean and ObserverMethod objects for the discovered beans, but before detecting deployment problems.

The event object must be of type javax.enterprise.inject.spi.AfterBeanDiscovery:

public interface AfterBeanDiscovery {
    public void addDefinitionError(Throwable t);
    public void addBean(Bean<?> bean);
    public void addObserverMethod(ObserverMethod<?> observerMethod);
    public void addContext(Context context);
}
  • addDefinitionError() registers a definition error with the container, causing the container to abort deployment after all observers have been notified.

  • addBean() fires an event of type ProcessBean containing the given Bean and then registers the Bean with the container, thereby making it available for injection into other beans. The given Bean may implement Interceptor or Decorator.

  • addObserverMethod() fires an event of type ProcessObserverMethod containing the given ObserverMethod and then registers the ObserverMethod with the container, thereby making it available for event notifications.

  • addContext() registers a custom Context object with the container.

A portable extension may take advantage of this event to register beans, interceptors, decorators, observer methods and custom context objects with the container.

void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) { ... }

If any observer method of the AfterBeanDiscovery event throws an exception, the exception is treated as a definition error by the container.

11.5.3. AfterDeploymentValidation event

The container must fire a third event after it has validated that there are no deployment problems and before creating contexts or processing requests.

The event object must be of type javax.enterprise.inject.spi.AfterDeploymentValidation:

public interface AfterDeploymentValidation {
    public void addDeploymentProblem(Throwable t);
}
  • addDeploymentProblem() registers a deployment problem with the container, causing the container to abort deployment after all observers have been notified.

void afterDeploymentValidation(@Observes AfterDeploymentValidation event, BeanManager manager) { ... }

If any observer method of the AfterDeploymentValidation event throws an exception, the exception is treated as a deployment problem by the container.

The container must not allow any request to be processed by the deployment until all observers of this event return.

11.5.4. BeforeShutdown event

The container must fire a final event after it has finished processing requests and destroyed all contexts.

The event object must be of type javax.enterprise.inject.spi.BeforeShutdown:

public interface BeforeShutdown {}
void beforeShutdown(@Observes BeforeShutdown event, BeanManager manager) { ... }

If any observer method of the BeforeShutdown event throws an exception, the exception is ignored by the container.

11.5.5. ProcessAnnotatedType event

The container must fire an event for each Java class or interface it discovers in a bean archive, before it reads the declared annotations.

The event object must be of type javax.enterprise.inject.spi.ProcessAnnotatedType<X>, where X is the class.

public interface ProcessAnnotatedType<X> {
    public AnnotatedType<X> getAnnotatedType();
    public void setAnnotatedType(AnnotatedType<X> type);
    public void veto();
}
  • getAnnotatedType() returns the AnnotatedType object that will be used by the container to read the declared annotations.

  • setAnnotatedType() replaces the AnnotatedType.

  • veto() forces the container to ignore the type.

Any observer of this event is permitted to wrap and/or replace the AnnotatedType. The container must use the final value of this property, after all observers have been called, to discover the types and read the annotations of the program elements.

For example, the following observer decorates the AnnotatedType for every class that is discovered by the container.

<T> void decorateAnnotatedType(@Observes ProcessAnnotatedType<T> pat) {
    pat.setAnnotatedType( decorate( pat.getAnnotatedType() ) );
}

If any observer method of a ProcessAnnotatedType event throws an exception, the exception is treated as a definition error by the container.

11.5.6. ProcessInjectionTarget event

The container must fire an event for every Java EE component class supporting injection that may be instantiated by the container at runtime, including every managed bean declared using @ManagedBean, EJB session or message-driven bean, enabled bean, enabled interceptor or enabled decorator.

The event object must be of type javax.enterprise.inject.spi.ProcessInjectionTarget<X>, where X is the managed bean class, session bean class or Java EE component class supporting injection.

public interface ProcessInjectionTarget<X> {
    public AnnotatedType<X> getAnnotatedType();
    public InjectionTarget<X> getInjectionTarget();
    public void setInjectionTarget(InjectionTarget<X> injectionTarget);
    public void addDefinitionError(Throwable t);
}
  • getAnnotatedType() returns the AnnotatedType representing the managed bean class, session bean class or other Java EE component class supporting injection.

  • getInjectionTarget() returns the InjectionTarget object that will be used by the container to perform injection.

  • setInjectionTarget() replaces the InjectionTarget.

  • addDefinitionError() registers a definition error with the container, causing the container to abort deployment after bean discovery is complete.

Any observer of this event is permitted to wrap and/or replace the InjectionTarget. The container must use the final value of this property, after all observers have been called, whenever it performs injection upon the managed bean, session bean or other Java EE component class supporting injection.

For example, this observer decorates the InjectionTarget for all servlets.

<T extends Servlet> void decorateServlet(@Observes ProcessInjectionTarget<T> pit) {
    pit.setInjectionTarget( decorate( pit.getInjectionTarget() ) );
}

If any observer method of a ProcessInjectionTarget event throws an exception, the exception is treated as a definition error by the container.

11.5.7. ProcessProducer event

The container must fire an event for each producer method or field of each enabled bean, including resources.

The event object must be of type javax.enterprise.inject.spi.ProcessProducer<T, X>, where T is the bean class of the bean that declares the producer method or field and X is the return type of the producer method or the type of the producer field.

public interface ProcessProducer<T, X> {
    public AnnotatedMember<T> getAnnotatedMember();
    public Producer<X> getProducer();
    public void setProducer(Producer<X> producer);
    public void addDefinitionError(Throwable t);
}
  • getAnnotatedMember() returns the AnnotatedField representing the producer field or the AnnotatedMethod representing the producer method.

  • getProducer() returns the Producer object that will be used by the container to call the producer method or read the producer field.

  • setProducer() replaces the Producer.

  • addDefinitionError() registers a definition error with the container, causing the container to abort deployment after bean discovery is complete.

Any observer of this event is permitted to wrap and/or replace the Producer. The container must use the final value of this property, after all observers have been called, whenever it calls the producer or disposer.

For example, this observer decorates the Producer for all producer methods and fields of type EntityManager.

void decorateEntityManager(@Observes ProcessProducer<?, EntityManager> pp) {
    pit.setProducer( decorate( pp.getProducer() ) );
}

If any observer method of a ProcessProducer event throws an exception, the exception is treated as a definition error by the container.

11.5.8. ProcessBean event

The container must fire an event for each enabled bean, interceptor or decorator deployed in a bean archive, before registering the Bean object. No event is fired for any @New qualified bean, defined in Section 3.12, “@New qualified beans”.

The event object type in the package javax.enterprise.inject.spi depends upon what kind of bean was discovered:

  • For a managed bean with bean class X, the container must raise an event of type ProcessManagedBean<X>.

  • For a session bean with bean class X, the container must raise an event of type ProcessSessionBean<X>.

  • For a producer method with method return type X of a bean with bean class T, the container must raise an event of type ProcessProducerMethod<T, X>.

  • For a producer field with field type X of a bean with bean class T, the container must raise an event of type ProcessProducerField<T, X>.

Resources are considered to be producer fields.

The interface javax.enterprise.inject.spi.ProcessBean is a supertype of all these event types:

public interface ProcessBean<X> {
    public Annotated getAnnotated();
    public Bean<X> getBean();
    public void addDefinitionError(Throwable t);
}
  • getAnnotated() returns the AnnotatedType representing the bean class, the AnnotatedMethod representing the producer method, or the AnnotatedField representing the producer field.

  • getBean() returns the Bean object that is about to be registered. The Bean may implement Interceptor or Decorator.

  • addDefinitionError() registers a definition error with the container, causing the container to abort deployment after bean discovery is complete.

public interface ProcessSessionBean<X> 
        extends ProcessManagedBean<Object> {
    public String getEjbName();
    public SessionBeanType getSessionBeanType();
}
  • getEjbName() returns the EJB name of the session bean.

  • getSessionBeanType() returns a javax.enterprise.inject.spi.SessionBeanType representing the kind of session bean.

public enum SessionBeanType { STATELESS, STATEFUL, SINGLETON }
public interface ProcessManagedBean<X> 
        extends ProcessBean<X> {
    public AnnotatedType<X> getAnnotatedBeanClass();
}
public interface ProcessProducerMethod<T, X> 
        extends ProcessBean<X> {
    public AnnotatedMethod<T> getAnnotatedProducerMethod();
    public AnnotatedParameter<T> getAnnotatedDisposedParameter();
}
public interface ProcessProducerField<T, X> 
        extends ProcessBean<X> {
    public AnnotatedField<T> getAnnotatedProducerField();
}

If any observer method of a ProcessBean event throws an exception, the exception is treated as a definition error by the container.

11.5.9. ProcessObserverMethod event

The container must fire an event for each observer method of each enabled bean, before registering the ObserverMethod object.

The event object must be of type javax.enterprise.inject.spi.ProcessObserverMethod<T, X>, where T is the bean class of the bean that declares the observer method and X is the observed event type of the observer method.

public interface ProcessObserverMethod<T, X> {
    public AnnotatedParameter<T> getAnnotatedEventParameter();
    public ObserverMethod<X> getObserverMethod();
    public void addDefinitionError(Throwable t);
}
  • getAnnotatedEventParameter() returns the AnnotatedParameter representing the event parameter.

  • getObserverMethod() returns the ObserverMethod object that will be used by the container to call the observer method.

  • addDefinitionError() registers a definition error with the container, causing the container to abort deployment after bean discovery is complete.

If any observer method of a ProcessObserverMethod event throws an exception, the exception is treated as a definition error by the container.