Skip to content

Latest commit

 

History

History
233 lines (146 loc) · 13.1 KB

packagingdeployment_full.asciidoc

File metadata and controls

233 lines (146 loc) · 13.1 KB

Packaging and deployment in {cdi_full}

This chapter replaces [packaging_deployment] for the purpose of {cdi_full}. The [packaging_deployment] chapter should be considered merely informative. In {cdi_full}, the term deployment time always means during application startup.

When an application is started, the container must perform bean discovery, detect definition errors and deployment problems and raise events that allow portable extensions to integrate with the deployment lifecycle.

Bean discovery is the process of determining:

  • The bean archives that exist in the application, and the beans they contain

  • Which alternatives, interceptors and decorators are enabled for each bean archive

  • The ordering of enabled interceptors and decorators

Additional beans may be registered programmatically with the container by the application or a portable extension after the automatic bean discovery completes. Portable extensions may even integrate with the process of building the Bean object for a bean, to enhance the container’s built-in functionality.

Bean archives in {cdi_full}

Bean classes of enabled beans must be deployed in bean archives.

A bean archive has a bean discovery mode of all, annotated or none. A bean archive which contains a beans.xml file with no version has a default bean discovery mode of all. A bean archive which contains a beans.xml file with version 1.1 (or later) must specify the bean-discovery-mode attribute. The default value for the attribute is annotated.

An archive which:

  • contains a beans.xml file with the bean-discovery-mode of none, or,

  • contains a portable extension or a build compatible extension and no beans.xml file

is not a bean archive.

An explicit bean archive is an archive which contains a beans.xml file:

  • with a version number of 1.1 (or later), with the bean-discovery-mode of all, or,

  • with no version number.

An implicit bean archive is:

  • an archive which contains a beans.xml file that is empty, or,

  • any other archive which contains one or more bean classes with a bean defining annotation as defined in [bean_defining_annotations].

When determining which archives are bean archives, the container must consider:

  • Library jars

  • Directories in the JVM classpath

Non Jakarta EE containers may or may not provide support for war, EJB jar or rar bean archives.

The beans.xml file must be named:

  • META-INF/beans.xml.

For compatibility with CDI versions prior to 4.0, {cdi_full} products must contain an option that causes an archive with empty beans.xml to be considered an explicit bean archive.

The container searches for beans in all bean archives in the application classpath.

If a bean class is deployed in two different bean archives, non-portable behavior results. Portable applications must deploy each bean class in no more than one bean archive.

Explicit bean archives may contain classes which are not deployed as beans. For example a bean archive might contain an abstract class not annotated with @Decorator.

Implicit bean archives are likely to contain classes which are not deployed as beans.

An extension may be deployed in any archive, including those that are not bean archives.

Application initialization lifecycle in {cdi_full}

When an application is started, the container performs the following steps:

  • First, the container must search for service providers for the service jakarta.enterprise.inject.spi.Extension defined in [init_events], instantiate a single instance of each service provider, and search the service provider class for observer methods of initialization events.

  • Next, the container must fire an event of type BeforeBeanDiscovery, as defined in [before_bean_discovery].

  • Next, the container must perform type discovery, as defined in Type discovery in {cdi_full}.

  • Next, the container must fire an event of type AfterTypeDiscovery, as defined in [after_type_discovery].

  • Next, the container must perform bean discovery, as defined in Bean discovery in {cdi_full}.

  • Next, the container must fire an event of type AfterBeanDiscovery, as defined in [after_bean_discovery], and abort initialization of the application if any observer registers a definition error.

  • Next, the container must detect deployment problems by validating bean dependencies and specialization and abort initialization of the application if any deployment problems exist, as defined in [exceptions].

  • Next, the container must fire an event of type AfterDeploymentValidation, as defined in [after_deployment_validation], and abort initialization of the application if any observer registers a deployment problem.

  • Finally, the container begins directing requests to the application.

Application shutdown lifecycle in {cdi_full}

When an application is stopped, the container performs the following steps:

  • First, the container must destroy all contexts.

  • Finally, the container must fire an event of type BeforeShutdown, as defined in [before_shutdown].

Type and Bean discovery in {cdi_full}

The container automatically discovers managed beans (according to the rules of [what_classes_are_beans]) in bean archives and searches the bean classes for producer methods, producer fields, disposer methods and observer methods.

Type discovery in {cdi_full}

First the container must discover types. The container discovers:

  • each Java class, interface (excluding the special kind of interface declaration annotation type) or enum deployed in an explicit bean archive, and

  • each Java class with a bean defining annotation in an implicit bean archive,

that is not excluded from discovery by an exclude filter as defined in Exclude filters.

Then, for every type discovered the container must create an AnnotatedType representing the type and fire an event of type ProcessAnnotatedType, as defined in [process_annotated_type].

If an extension calls BeforeBeanDiscovery.addAnnotatedType() or AfterTypeDiscovery.addAnnotatedType(), the type passed must be added to the set of discovered types and the container must fire an event of type ProcessSyntheticAnnotatedType for every type added, as defined in [process_annotated_type]+

Exclude filters

Exclude filters are defined by <exclude> elements in the beans.xml for the bean archive as children of the <scan> element. By default an exclude filter is active. If the exclude filter definition contains:

  • a child element named <if-class-available> with a name attribute, and the classloader for the bean archive can not load a class for that name, or

  • a child element named <if-class-not-available> with a name attribute, and the classloader for the bean archive can load a class for that name, or

  • a child element named <if-system-property> with a name attribute, and there is no system property defined for that name, or

  • a child element named <if-system-property> with a name attribute and a value attribute, and there is no system property defined for that name with that value.

then the filter is inactive.

If the filter is active, and:

  • the fully qualified name of the type being discovered matches the value of the name attribute of the exclude filter, or

  • the package name of the type being discovered matches the value of the name attribute with a suffix ".*" of the exclude filter, or

  • the package name of the type being discovered starts with the value of the name attribute with a suffix ".**" of the exclude filter

then we say that the type is excluded from discovery.

For example, consider the follow beans.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
       bean-discovery-mode="all" version="3.0">

    <scan>
        <exclude name="com.acme.rest.*" />

        <exclude name="com.acme.faces.**">
            <if-class-not-available name="jakarta.faces.context.FacesContext"/>
        </exclude>

        <exclude name="com.acme.verbose.*">
            <if-system-property name="verbosity" value="low"/>
        </exclude>

        <exclude name="com.acme.ejb.**">
            <if-class-available name="jakarta.enterprise.inject.Model"/>
            <if-system-property name="exclude-ejbs"/>
        </exclude>
    </scan>

</beans>

The first exclude filter will exclude all classes in com.acme.rest package. The second exclude filter will exclude all classes in the com.acme.faces package, and any subpackages, but only if JSF is not available. The third exclude filter will exclude all classes in the com.acme.verbose package if the system property verbosity has the value low. The fourth exclude filter will exclude all classes in the com.acme.ejb package, and any subpackages if the system property exclude-ejbs is set (with any value) and at the same time, the jakarta.enterprise.inject.Model class is available to the classloader.

Trimmed bean archive

An explicit bean archive may be marked as 'trimmed' by adding the <trim /> element to its beans.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
        version="3.0">

    <trim/>
</beans>

If an explicit bean archive contains the <trim/> element in its beans.xml file, types that don’t have either a bean defining annotation (as defined in [bean_defining_annotations]) or any scope annotation, are removed from the set of discovered types.

Bean discovery in {cdi_full}

For every type in the set of discovered types (as defined in Type discovery in {cdi_full}), the container must:

  • inspect the type metadata to determine if it is a bean, and then

  • detect definition errors by validating the class and its metadata, and then

  • if the class is a managed bean, fire an event of type ProcessInjectionPoint for each injection point in the class, as defined in [process_injection_point], and then

  • if the class is a managed bean, fire an event of type ProcessInjectionTarget, as defined in [process_injection_target], and then

  • determine which alternatives, interceptors and decorators are enabled, according to the rules defined in [enablement], [enabled_interceptors] and [enabled_decorators], and then

  • if the class is an enabled bean, interceptor or decorator, fire an event of type ProcessBeanAttributes, as defined in [process_bean_attributes], and then

  • if the class is an enabled bean, interceptor or decorator and if ProcessBeanAttributes.veto() wasn’t called in previous step, fire an event which is a subtype of ProcessBean, as defined in [process_bean].

For each enabled bean, the container must search the class for producer methods and fields, as defined in [producer_method] and in [producer_field], including resources, and for each producer:

  • if it is a producer method, fire an event of type ProcessInjectionPoint for each injection point in the method parameters, as defined in [process_injection_point], and then

  • fire an event of type ProcessProducer, as defined in [process_producer], and then

  • if the producer method or field is enabled, fire an event of type ProcessBeanAttributes, as defined in [process_bean_attributes], and then

  • if the producer method or field is enabled and if ProcessBeanAttributes.veto() wasn’t called in previous step, fire an event which is a subtype of ProcessBean, as defined in [process_bean].

For each enabled bean, the container must search for disposer methods as defined in [disposer_method], and for each disposer method:

  • fire an event of type ProcessInjectionPoint for each injection point in the method parameters, as defined in [process_injection_point].

For each enabled bean, the container must search the class for observer methods, and for each observer method:

Then, the container registers the Bean and ObserverMethod objects:

  • For each enabled bean that is not an interceptor or decorator, the container registers an instance of the Bean interface defined in [bean].

  • For each enabled interceptor, the container registers an instance of the Interceptor interface defined in [interceptor].

  • For each enabled decorator, the container registers an instance of the Decorator interface defined in [decorator].

  • For each observer method of every enabled bean, the container registers an instance of the ObserverMethod interface defined in [observer_method].